备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e86d5536bdd7e714d9e34774b1bb9798
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using asap.core.common;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class SplashAnimation : MonoBehaviour, IPoolableObject
{
private IObjectPool pool;
private float m_Timer;
private bool m_IsTiming = false;
private void Update()
{
if (m_IsTiming == false) return;
m_Timer -= Time.deltaTime;
if (m_Timer <= 0)
{
ReturnPool();
m_Timer = 0f;
m_IsTiming = false;
}
}
public void SetTimer(float timer)
{
m_Timer = timer;
}
private void OnEnable()
{
m_IsTiming = true;
}
private void OnDisable()
{
m_IsTiming = false;
}
public void OnDespawn()
{
}
public void OnPoolCreate(IObjectPool objectPool)
{
pool = objectPool;
}
public void OnPoolDestroy()
{
pool = null;
}
public void OnSpawn()
{
}
public void ReturnPool()
{
pool?.DespawnObject(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd67af5831fd5df46b00edd8bba1489c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class SprayAnimation : MonoBehaviour
{
[Tooltip("粒子特效")]
[SerializeField]
private ParticleSystem[] m_ParticleSystems = null;
#region
public void PlayEffect()
{
if (m_ParticleSystems != null)
{
int count = m_ParticleSystems.Length;
for (int i = 0; i < count; i++)
{
m_ParticleSystems[i].gameObject.SetActive(true);
m_ParticleSystems[i].Play();
}
}
}
public void StopEffect()
{
if (m_ParticleSystems != null)
{
int count = m_ParticleSystems.Length;
for (int i = 0; i < count; i++)
{
m_ParticleSystems[i].Stop();
m_ParticleSystems[i].gameObject.SetActive(false);
}
}
}
public void DisableEffect()
{
if (m_ParticleSystems != null)
{
int count = m_ParticleSystems.Length;
for (int i = 0; i < count; i++)
{
m_ParticleSystems[i].gameObject.SetActive(false);
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a25e27952b497654dbb4f7729bb43ede
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace game
{
public class UpdateOperationSet
{
public UnityAction<float> Update = null; // 更新事件
public Func<bool> IsUpdateOver = null;
public Func<int, bool> Callback = null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c0166e80b4367d4aae2c34c83942c7b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
using cfg;
using PaintIn3D;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public enum EventWashingStuffType
{
Invalid, // 无效类型
Foam, // 泡沫类型
Unload, // 移出物体类别
Assembling, // 组装物体类别
CleaningArea, // 清洗区域
Trash, // 垃圾
Barnacle, // 藤壶
AssemblingGlass, // 组装物体,玻璃类别
UnloadGlass, // 移出物体,玻璃类别
}
public enum EventWashingActionStatus
{
Invalid, // 无效状态
Preparing, // 准备状态
Executing, // 执行状态
Stopping, // 停止状态
Ending, // 结束状态
}
#region PlayFab
public class EventWashingConfig
{
public const string SAVE_DATA_KEY = "ewdk"; // event washing data key
}
#endregion
#region
public enum EventWashingCameraMoveDirection
{
Forward, // 向前
Backward // 向后
}
public class EventWashingCameraMoveData
{
public EventWashingCameraMoveDirection direction;
public EventWashingCameraMoveData(EventWashingCameraMoveDirection direction)
{
this.direction = direction;
}
}
public class EventWashingCameraStopData
{
}
#endregion
#region
// 手势跟随数据
public class EventWashingGestureFollowPositionData
{
public Vector2 position;
public bool isFollowing;
public EventWashingGestureFollowPositionData(Vector2 position, bool isFollowing)
{
this.position = position;
this.isFollowing = isFollowing;
}
}
// 清洗喷枪跟随数据
public class EventWashingCleanerFollowPositionData
{
public Vector3 position;
public Vector3 normal;
public EventWashingCleanerFollowPositionData(Vector3 position, Vector3 normal)
{
this.position = position;
this.normal = normal;
}
}
public class EventWashingMonitoringFoamProgressData
{
public float progress;
public EventWashingMonitoringFoamProgressData(float progress)
{
this.progress = progress;
}
}
#endregion
#region
public class EventWashingGameData
{
public string resName;
public EventWashingOperation gameType;
public int gameID;
public EventWashingTool toolType;
public int toolID;
public EventWashingGameData(string resName, EventWashingOperation gameType, int gameID, EventWashingTool toolType, int toolID)
{
this.resName = resName;
this.gameType = gameType;
this.gameID = gameID;
this.toolType = toolType;
this.toolID = toolID;
}
}
public class EventWashingGameOverData { }
// 结束语
public class EventWashingConclusionData { }
// 项目结束
public class EventWashingStepOverData { }
public class EventWashingAllGameOverData { }
#endregion
#region
public class EventWashingTokenUpdateData { }
#endregion
#region
public class EventWashingToolEnter1stStageData { }
public class EventWashingToolExit1stStageData { }
public class EventWashingToolEnter2ndStageData { }
public class EventWashingToolExit2ndStageData { }
#endregion
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ff00f79a48603c14f842ad93c71c7495
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,303 @@
using asap.core;
using GameCore;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using UnityEngine.AddressableAssets;
using Cinemachine;
using cfg;
namespace game
{
public class EventWashingController : MonoBehaviour
{
[Tooltip("虚拟摄像机")]
[SerializeField] private CinemachineVirtualCamera m_VirtualCamera;
[Tooltip("虚拟摄像机移动管理器")]
public CameraFollowPathMoveController m_VirtualCameraMoveController;
[Tooltip("工具初始位置")]
[SerializeField] private List<Transform> m_ToolsInitTransfomList = new List<Transform>();
private List<OperatingToolsBase> m_Tools;
#region
WashingGameCollection m_GameCollection; // 游戏合集
WashingGameBase m_Game; // 当前游戏
GameObject m_GameNode;
GameObject m_ToolNode;
EventWashingDataManager m_DataManager;
/// <summary>
/// 加载游戏
/// </summary>
/// <param name="gameData"></param>
public async void LoadGame(EventWashingGameData gameData)
{
ILoadResourceService loadResourceService = GContext.container.Resolve<ILoadResourceService>();
await loadResourceService.Load(gameData.resName);
await UIManager.Instance.ShowUI(UITypes.CloudTransitionPanel);
var gameNode = await Addressables.InstantiateAsync(gameData.resName, transform, true).Task;
if (gameNode != null )
{
if (m_GameNode != null)
{
Addressables.ReleaseInstance(m_GameNode);
m_GameNode = null;
}
m_GameNode = gameNode;
m_GameCollection = m_GameNode.GetComponent<WashingGameCollection>();
int count = m_GameCollection.GameList.Count;
for (int i = 0; i < count; i++)
{
var game = m_GameCollection.GameList[i];
if (game != null)
game.InitGame(gameData.resName);
else
continue;
if (game.GameType == gameData.gameType && game.GameID == gameData.gameID)
{
m_Game = game;
}
else
{
game.gameObject.SetActive(false);
}
}
if (m_Game != null)
{
m_Game.ResetAndInitData(m_VirtualCamera, m_VirtualCameraMoveController, GetTool(gameData.toolType, gameData.toolID));
m_Game.Fresh(m_DataManager);
m_Game.EnterGame();
m_Game.gameObject.SetActive(true);
}
}
GContext.Publish(new EndTransition());
}
public OperatingToolsBase GetTool(EventWashingTool toolType, int toolID)
{
OperatingToolsBase toolBase = null;
foreach (var tool in m_Tools)
{
if (tool == null) continue;
if (tool.ToolType == toolType && tool.ToolID == toolID)
{
tool.gameObject.SetActive(true);
toolBase = tool;
}
else
{
tool.gameObject.SetActive(false);
}
}
if (toolBase != null) return toolBase;
return null;
}
public void GameOver(EventWashingGameOverData data)
{
EventWashingStep washingStep = m_DataManager.GetCurrentEventStep();
// 展示奖励界面
List<ItemData> itemDataList = GContext.container.Resolve<PlayerItemData>().AddItemByDrop(washingStep.DropID, true, RewardType.NormalOne);
AddDropStatisticalData(washingStep.DropID, itemDataList);
GContext.Publish(new ShowData());
// 清空当前游戏信息
m_DataManager.WashingData.Percent = 1f;
m_DataManager.WashingData.Energy = 0f;
m_DataManager.WashingData.OmitPercent = 0f;
m_DataManager.WashingData.IsOver = true;
m_DataManager.WashingData.ConsumedToken = 0;
}
private void OnRewardPanelClose(RewardPanelClose rewardPanelClose)
{
EventWashingData washingData = m_DataManager.WashingData;
// 获取最新游戏数据
EventWashingStep washingStep = m_DataManager.GetNextEventStep();
if (washingStep == null)
{
// 活动结束
m_DataManager.WashingData.IsAllGameOver = true;
FishingYachtAct.Publish<EventWashingAllGameOverData>(new EventWashingAllGameOverData());
}
else
{
// 卸载旧游戏
UnloadGame();
// 加载新游戏
SwitchPlayerToGame();
}
}
/// <summary>
/// 卸载游戏
/// </summary>
public void UnloadGame()
{
if (m_Game != null)
{
m_Game.GameOver();
m_Game.gameObject.SetActive(false);
m_Game = null;
}
}
private void InitTools()
{
int count = m_Tools.Count;
for (int i = 0; i < count; i++)
{
var tool = m_Tools[i];
tool.InitTransfom = m_ToolsInitTransfomList[i];
if (tool != null)
{
tool.InitTool();
tool.gameObject.SetActive(false);
}
}
}
private void SwitchPlayerToGame()
{
if (m_DataManager.WashingData == null)
{
EnterFreshGame();
}
else
{
ContinueGame();
}
}
private void EnterFreshGame()
{
EventWashingStep washingStep = m_DataManager.GetFreshEventStep();
if (washingStep == null) return;
EventWashingData washingData = m_DataManager.WashingData;
if (washingData == null) return;
string res = string.Format("GC_{0:D}_{1:D}_{2:D}", washingData.WashingID, washingData.StageID, washingData.StepID);
FishingYachtAct.Publish<EventWashingGameData>(new EventWashingGameData(res, washingStep.GameType, washingStep.GameID, washingStep.ToolType, washingStep.ToolID));
}
private void ContinueGame()
{
EventWashingStep washingStep = m_DataManager.GetCurrentEventStep();
if (washingStep == null)
{
washingStep = m_DataManager.GetFreshEventStep();
if (washingStep == null) return;
}
EventWashingData washingData = m_DataManager.WashingData;
if (washingData == null) return;
string res = string.Format("GC_{0:D}_{1:D}_{2:D}", washingData.WashingID, washingData.StageID, washingData.StepID);
FishingYachtAct.Publish<EventWashingGameData>(new EventWashingGameData(res, washingStep.GameType, washingStep.GameID, washingStep.ToolType, washingStep.ToolID));
}
#endregion
#region
private void ClearGameData()
{
if (m_DataManager == null || m_DataManager.WashingData == null) return;
m_DataManager.WashingData.StepItems.Clear();
m_DataManager.WashingData.Energy = 0f;
m_DataManager.WashingData.Percent = 0f;
m_DataManager.WashingData.OmitPercent = 0f;
m_DataManager.WashingData.IsOver = false;
m_DataManager.WashingData.ConsumedToken = 0;
}
private void AddDropStatisticalData(int dropID, List<ItemData> itemDataList)
{
#if AGG
using (var e = GEvent.GameEvent("event_washing_reward"))
{
e.AddContent("step_id", m_DataManager.WashingData.StepID)
.AddContent("independent_id", m_DataManager.WashingData.ConsumedToken)
.AddContent("reward_id", dropID);
if (itemDataList != null)
{
for (int i = 0; i < itemDataList.Count; i++)
{
if (itemDataList[i].id == 1001)
{
e.AddContent("reward_hook", itemDataList[i].count);
}
//else if (itemDataList[i].id == 1002)
//{
// e.AddContent("reward_cash", itemDataList[i].count);
//}
}
}
}
#endif
}
#endregion
#region
// Start is called before the first frame update
async void Start()
{
m_DataManager = GContext.container.Resolve<EventWashingDataManager>();
// 加载工具
m_ToolNode = await Addressables.InstantiateAsync("EventWashingTools", transform, true).Task;
if (m_ToolNode != null)
{
ToolCollection toolCollection = m_ToolNode.GetComponent<ToolCollection>();
this.m_Tools = toolCollection.Tools;
}
InitTools();
// 加载游戏
FishingYachtAct.Subscribe<EventWashingGameData>(LoadGame);
// 游戏结束
FishingYachtAct.Subscribe<EventWashingGameOverData>(GameOver);
// 监听关闭奖励面板
GContext.OnEvent<RewardPanelClose>().Subscribe(OnRewardPanelClose).AddTo(FishingYachtAct.Disposables);
if (m_VirtualCameraMoveController != null) m_VirtualCameraMoveController.enabled = false;
m_DataManager.FixWashingData();
SwitchPlayerToGame();
//string bgm = m_DataManager.GetBgm();
//if (string.IsNullOrEmpty(bgm) == false) GContext.Publish(new EventBGMSound(bgm));
}
private void OnDisable()
{
if (m_ToolNode != null)
{
Addressables.ReleaseInstance(m_ToolNode);
m_ToolNode = null;
}
if (m_GameNode != null)
{
Addressables.ReleaseInstance(m_GameNode);
m_GameNode = null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 332df60b42f568d47837598fdc0333ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 85fe8ae15534a334db05e933ea9bdab4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
//
// OutlineFill.shader
// QuickOutline
//
// Created by Chris Nolet on 2/21/18.
// Copyright © 2018 Chris Nolet. All rights reserved.
//
Shader "Bamboo/Outline Fill" {
Properties {
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 0
_OutlineColor("Outline Color", Color) = (1, 1, 1, 1)
_OutlineWidth("Outline Width", Range(0, 10)) = 2
}
SubShader {
Tags {
"Queue" = "Transparent+110"
"RenderType" = "Transparent"
"DisableBatching" = "True"
}
Pass {
Name "Fill"
Cull Off
ZTest [_ZTest]
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
Stencil {
Ref 1
Comp NotEqual
}
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float3 smoothNormal : TEXCOORD3;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 position : SV_POSITION;
fixed4 color : COLOR;
UNITY_VERTEX_OUTPUT_STEREO
};
uniform fixed4 _OutlineColor;
uniform float _OutlineWidth;
v2f vert(appdata input) {
v2f output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
float3 normal = any(input.smoothNormal) ? input.smoothNormal : input.normal;
float3 viewPosition = UnityObjectToViewPos(input.vertex);
float3 viewNormal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, normal));
output.position = UnityViewToClipPos(viewPosition + viewNormal * -viewPosition.z * _OutlineWidth / 1000.0);
output.color = _OutlineColor;
return output;
}
fixed4 frag(v2f input) : SV_Target {
return input.color;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e83e6b9b79a08e442ade24860c28cd0f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
//
// OutlineMask.shader
// QuickOutline
//
// Created by Chris Nolet on 2/21/18.
// Copyright © 2018 Chris Nolet. All rights reserved.
//
Shader "Bamboo/Outline Mask" {
Properties {
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 0
}
SubShader {
Tags {
"Queue" = "Transparent+100"
"RenderType" = "Transparent"
}
Pass {
Name "Mask"
Cull Off
ZTest [_ZTest]
ZWrite Off
ColorMask 0
Stencil {
Ref 1
Pass Replace
}
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 9654e637a0e8c2947b4cc556d0e64c6f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
Shader "Bamboo/RimLight"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_RimColor ("Rim Color", color) = (1.0, 0, 0, 1.0)
_RimPower ("Rim Power", Range(0.0001, 3.0)) = 1.0
_RimIntensity ("Rim Intensity", Range(0, 100.0)) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 worldNormal : TEXCOORD1;
float3 worldViewDir : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _RimColor;
half _RimPower;
float _RimIntensity;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldViewDir = WorldSpaceViewDir(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldViewDir = normalize(i.worldViewDir);
fixed4 diffuse = tex2D(_MainTex, i.uv);
// powÆðË¥¼õ×÷ÓÃ
fixed4 rimLight = _RimColor * pow(saturate(1.0 - dot(worldNormal, worldViewDir)), 1.0 / _RimPower) * _RimIntensity;
//fixed4 rimLight = _RimColor * saturate(1.0 - dot(worldNormal, worldViewDir)) * _RimIntensity;
fixed3 color = diffuse.rgb + rimLight;
return fixed4(color, 1.0);
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1fb5272ce26d5b2448fedc0c49861d1e
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3dd0a5074db1af74db0b89f7a87c4053
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class WashingShipBase : MonoBehaviour
{
#region
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db75b49295faeac4589e631164ea1edb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7ebe1ac190ea8d2498182d6424fe0e8d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,241 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace game
{
public class LongPressStuffBase : MonoBehaviour
{
[Tooltip("物品ID")]
public int ID = 0;
[Tooltip("需要消耗的时间")]
[SerializeField] protected float m_ConsumeTime = 3f;
[Tooltip("是否需要呼吸变色功能,默认开启。")]
public bool m_IsBreathing = true;
[Tooltip("需要改变颜色的渲染器")]
public Renderer[] m_Renderers = null;
[Tooltip("吸气时间")]
public float m_BreatheInTime = 1f;
[Tooltip("呼气时间")]
public float m_BreatheOutTime = 1f;
[Tooltip("憋气时间")]
public float m_HoldBreathTime = 2f;
[Tooltip("颜色")]
public Color m_Color = Color.red;
#region
/// <summary>
/// 进度
/// </summary>
public float Progress
{
get
{
if (m_Status == EventWashingActionStatus.Executing || m_Status == EventWashingActionStatus.Stopping)
return m_CumulativeTime / m_ConsumeTime;
else if (m_Status == EventWashingActionStatus.Ending)
return 1f;
return 0f;
}
}
public float CumulativeConsumeTime
{
get
{
if (m_CumulativeTime < 0f)
{
m_CumulativeTime = 0f;
}
else if (m_CumulativeTime > m_ConsumeTime)
{
m_CumulativeTime = m_ConsumeTime;
}
return m_CumulativeTime;
}
}
/// <summary>
/// 启动操作
/// </summary>
/// <param name="overAction"></param>
public virtual void StartAction(UnityAction<LongPressStuffBase> overAction)
{
m_Status = EventWashingActionStatus.Executing;
m_OverAction = overAction;
}
/// <summary>
/// 停止操作
/// </summary>
public virtual void StopAction()
{
m_Status = EventWashingActionStatus.Stopping;
}
/// <summary>
/// 设置已经执行过的时间
/// </summary>
/// <param name="time"></param>
public void SetHaveExecutedTime(float time)
{
m_CumulativeTime = time;
}
/// <summary>
/// 设置结束
/// </summary>
public void SetOver()
{
m_CumulativeTime = m_ConsumeTime;
}
public bool IsOver()
{
return m_Status == EventWashingActionStatus.Ending;
}
#endregion
#region
private float m_Time = 0f;
private Color m_StartColor = Color.white;
private Color m_GapColor = Color.white;
private int m_State = 0;
public virtual void StartBreathing()
{
m_IsBreathing = true;
}
public virtual void StopBreathing()
{
m_IsBreathing = false;
}
private void InitMaterials()
{
if (m_Renderers == null) return;
m_GapColor = m_Color - m_StartColor;
}
private void UpdateMaterials()
{
if (m_Renderers == null || !m_IsBreathing) return;
if (m_State == 0)
{
m_Time += Time.deltaTime;
if (m_Time >= m_BreatheInTime)
{
m_Time = m_BreatheOutTime;
m_State = 1;
}
}
else if (m_State == 1)
{
m_Time -= Time.deltaTime;
if (m_Time <= 0f)
{
m_Time = 0f;
m_State = 2;
}
}
else if (m_State == 2)
{
m_Time += Time.deltaTime;
if (m_Time >= m_HoldBreathTime)
{
m_Time = 0f;
m_State = 0;
}
}
Color color = Color.white;
if (m_State == 0 || m_State == 1)
{
float scale = m_Time / m_BreatheInTime;
color = m_StartColor + scale * m_GapColor;
}
foreach (var renderer in m_Renderers)
{
int count = renderer.materials.Length;
for (int i = 0; i < count; i++)
{
Material material = renderer.materials[i];
material.SetColor("_BaseColor", color);
}
}
}
#endregion
#region
protected UnityAction<LongPressStuffBase> m_OverAction = null; // 结束事件
#endregion
#region &使
protected EventWashingActionStatus m_Status = EventWashingActionStatus.Invalid; // 状态
protected float m_CumulativeTime = 0f; // 累计时间
protected EventWashingStuffType m_Type = 0; // 物品类型
public float ConsumeTime { get => m_ConsumeTime; }
public void SetStatus(EventWashingActionStatus status)
{
m_Status = status;
}
protected virtual void UpdateState()
{
if (m_Status == EventWashingActionStatus.Executing)
{
m_CumulativeTime += Time.deltaTime;
if (m_CumulativeTime >= m_ConsumeTime)
{
m_CumulativeTime = m_ConsumeTime;
m_Status = EventWashingActionStatus.Ending;
if (m_OverAction != null)
{
m_OverAction.Invoke(this);
}
}
}
}
#endregion
#region
/// <summary>
/// 初始化
/// </summary>
public virtual void InitStuff()
{
InitMaterials();
}
// Start is called before the first frame update
protected virtual void Start()
{
InitStuff();
m_Status = EventWashingActionStatus.Invalid;
}
// Update is called once per frame
protected virtual void Update()
{
UpdateState();
UpdateMaterials();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb0556fd9afa9364997da5ea6ae7eff7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,79 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace game
{
public class StuffAssembling : LongPressStuffBase
{
[Tooltip("空置时所需材质球")]
public Material m_UnoccupiedMaterial;
#region
private List<List<Material>> m_BackupMaterials = new List<List<Material>>();
public void SwitchUnoccupiedMaterial()
{
if (m_UnoccupiedMaterial == null || m_Renderers == null) return;
int count = m_Renderers.Length;
for (int i = 0; i < count; i++)
{
var renderer = m_Renderers[i];
var materials = renderer.sharedMaterials.ToList();
// 备份原始材质球
List<Material> list = new List<Material>();
int tmpCount = materials.Count;
for (int j = 0; j < tmpCount; j++)
{
list.Add(materials[j]);
}
m_BackupMaterials.Add(list);
// 清空材质球
materials.Clear();
// 替换空置材质球
materials.Add(m_UnoccupiedMaterial);
renderer.materials = materials.ToArray();
}
}
public void RestoreMaterial()
{
if (m_Renderers == null) return;
int count = m_Renderers.Length;
for (int i = 0; i < count; i++)
{
var renderer = m_Renderers[i];
var materials = renderer.sharedMaterials.ToList();
// 清空材质球
materials.Clear();
var list = m_BackupMaterials[i];
int tmpCount = list.Count;
// 换回备份材质球
for(int j = 0;j < tmpCount; j++)
{
materials.Add((Material)list[j]);
}
renderer.materials = materials.ToArray();
}
}
#endregion
#region
public override void InitStuff()
{
base.InitStuff();
m_Type = EventWashingStuffType.Assembling;
SwitchUnoccupiedMaterial();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ba5e72162738294a8f8536bb073fe9f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,153 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class StuffBarnacle : LongPressStuffBase
{
[Tooltip("循环特效")]
[SerializeField]
private ParticleSystem[] m_LoopEffects = null;
[Tooltip("循环特效时间")]
[SerializeField]
private float m_LoopTime = 1.0f;
[Tooltip("最后一击特效")]
[SerializeField]
private ParticleSystem[] m_FinalBlowEffects = null;
[Tooltip("最后一击特效时间")]
[SerializeField]
private float m_FinalBlowTime = 0.3f;
#region
public override void StopAction()
{
base.StopAction();
Exit1stStage();
Exit2ndStage();
}
#endregion
#region &使
private bool m_IsRunning2rd = false;
private void Enter2ndStage()
{
m_IsBreathing = false;
if (m_IsRunning2rd) return;
m_IsRunning2rd = true;
int count = 0;
if (m_FinalBlowEffects != null)
{
count = m_FinalBlowEffects.Length;
for (int i = 0; i < count; i++)
{
m_FinalBlowEffects[i].gameObject.SetActive(true);
m_FinalBlowEffects[i].Play();
}
}
FishingYachtAct.Publish<EventWashingToolEnter2ndStageData>(new EventWashingToolEnter2ndStageData());
}
private void Exit2ndStage()
{
if (m_IsRunning2rd == false) return;
int count = 0;
if (m_FinalBlowEffects != null)
{
count = m_FinalBlowEffects.Length;
for (int i = 0; i < count; i++)
{
m_FinalBlowEffects[i].Stop();
m_FinalBlowEffects[i].gameObject.SetActive(false);
}
}
FishingYachtAct.Publish<EventWashingToolExit2ndStageData>(new EventWashingToolExit2ndStageData());
m_IsRunning2rd = false;
m_IsBreathing = true;
}
private bool m_IsRunning1st = false;
private void Enter1stStage()
{
m_IsBreathing = false;
if (m_IsRunning1st) return;
m_IsRunning1st = true;
int count = 0;
if (m_LoopEffects != null)
{
count = m_LoopEffects.Length;
for (int i = 0; i < count; i++)
{
m_LoopEffects[i].gameObject.SetActive(true);
m_LoopEffects[i].Play();
}
}
FishingYachtAct.Publish<EventWashingToolEnter1stStageData>(new EventWashingToolEnter1stStageData());
}
private void Exit1stStage()
{
if (m_IsRunning1st == false) return;
int count = 0;
if (m_LoopEffects != null)
{
count = m_LoopEffects.Length;
for (int i = 0; i < count; i++)
{
m_LoopEffects[i].Stop();
m_LoopEffects[i].gameObject.SetActive(false);
}
}
FishingYachtAct.Publish<EventWashingToolExit1stStageData>(new EventWashingToolExit1stStageData());
m_IsRunning1st = false;
m_IsBreathing = true;
}
protected override void UpdateState()
{
if (m_Status == EventWashingActionStatus.Executing)
{
m_CumulativeTime += Time.deltaTime;
if (m_CumulativeTime >= m_ConsumeTime)
{
Exit2ndStage();
m_CumulativeTime = m_ConsumeTime;
m_Status = EventWashingActionStatus.Ending;
if (m_OverAction != null)
{
m_OverAction.Invoke(this);
}
}
else if (m_CumulativeTime > m_LoopTime)
{
Exit1stStage();
Enter2ndStage();
}
else if (m_CumulativeTime >= 0f)
{
Enter1stStage();
}
}
}
#endregion
#region
public override void InitStuff()
{
base.InitStuff();
m_Type = EventWashingStuffType.Barnacle;
m_ConsumeTime = m_LoopTime + m_FinalBlowTime;
StopAction();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8def403aefb3ff4a8b91d80746d5378
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using PaintCore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace game
{
[RequireComponent(typeof(Collider))]
public class StuffCleaningArea : LongPressStuffBase
{
#region
public override void StartAction(UnityAction<LongPressStuffBase> overAction)
{
this.transform.GetComponent<Collider>().enabled = true;
}
public override void StopAction()
{
this.transform.GetComponent<Collider>().enabled = false;
}
#endregion
#region
public override void InitStuff()
{
base.InitStuff();
m_Type = EventWashingStuffType.CleaningArea;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dad6d7eb79f3ff943806763f29fc91ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace game
{
public class StuffTrash : LongPressStuffBase
{
private ToolForFollowerAndNormalPosition m_Cleaner;
private float m_Distance;
private float m_DisappearTime = 0.1f;
private bool m_Running = true;
private UnityAction<StuffTrash> m_OnCompleteAction = null; // 更新事件
#region
public void SetCleaner(ToolForFollowerAndNormalPosition cleaner, float distance, float disappearTime, UnityAction<StuffTrash> completeAction)
{
m_Cleaner = cleaner;
m_Distance = distance;
m_DisappearTime = disappearTime;
m_OnCompleteAction = completeAction;
m_Running = true;
}
private void CheckDistance()
{
if (m_Cleaner == null) return;
float distance = Vector3.Distance(this.transform.position, m_Cleaner.OperatingPoint);
if (distance <= m_Distance)
{
var self = this.gameObject;
//this.transform.DOKill();
this.transform.DOMove(m_Cleaner.OperatingPoint, m_DisappearTime).SetEase(Ease.OutQuad).OnComplete(() =>
{
self.SetActive(false);
});
this.transform.DOLookAt(m_Cleaner.OperatingPoint, m_DisappearTime).SetEase(Ease.OutQuad);
this.transform.DOScale(0.1f, m_DisappearTime).SetEase(Ease.Linear);
if (m_OnCompleteAction != null)
{
m_OnCompleteAction(this);
}
//this.gameObject.SetActive(false);
this.m_Status = EventWashingActionStatus.Ending;
StopAction();
}
}
#endregion
#region
public override void StartAction(UnityAction<LongPressStuffBase> overAction)
{
//base.StartAction(overAction);
m_Running = true;
}
public override void StopAction()
{
//base.StopAction();
m_Running = false;
}
#endregion
#region
public override void InitStuff()
{
base.InitStuff();
m_Type = EventWashingStuffType.Trash;
}
protected override void Update()
{
base.Update();
if (m_Running)
{
CheckDistance();
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b69635a03c5ffba48b0d499c00aacbd1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class StuffUnload : LongPressStuffBase
{
#region
public override void InitStuff()
{
base.InitStuff();
m_Type = EventWashingStuffType.Unload;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8a139756a6bb2854bbb0a84395fceb18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class StuffUnloadGlass : StuffUnload
{
[Tooltip("循环特效时间")]
[SerializeField]
private float m_LoopTime = 1.0f;
[Tooltip("最后一击特效时间")]
[SerializeField]
private float m_FinalBlowTime = 0.3f;
#region
public override void StopAction()
{
base.StopAction();
Exit1stStage();
Exit2ndStage();
}
#endregion
#region &使
private bool m_IsRunning2rd = false;
private void Enter2ndStage()
{
if (m_IsRunning2rd) return;
m_IsRunning2rd = true;
FishingYachtAct.Publish<EventWashingToolEnter2ndStageData>(new EventWashingToolEnter2ndStageData());
}
private void Exit2ndStage()
{
if (m_IsRunning2rd == false) return;
m_IsRunning2rd = false;
FishingYachtAct.Publish<EventWashingToolExit2ndStageData>(new EventWashingToolExit2ndStageData());
}
private bool m_IsRunning1st = false;
private void Enter1stStage()
{
if (m_IsRunning1st) return;
m_IsRunning1st = true;
FishingYachtAct.Publish<EventWashingToolEnter1stStageData>(new EventWashingToolEnter1stStageData());
}
private void Exit1stStage()
{
if (m_IsRunning1st == false) return;
m_IsRunning1st = false;
FishingYachtAct.Publish<EventWashingToolExit1stStageData>(new EventWashingToolExit1stStageData());
}
protected override void UpdateState()
{
if (m_Status == EventWashingActionStatus.Executing)
{
m_CumulativeTime += Time.deltaTime;
if (m_CumulativeTime >= m_ConsumeTime)
{
Exit2ndStage();
m_CumulativeTime = m_ConsumeTime;
m_Status = EventWashingActionStatus.Ending;
if (m_OverAction != null)
{
m_OverAction.Invoke(this);
}
}
else if (m_CumulativeTime > m_LoopTime)
{
Exit1stStage();
Enter2ndStage();
}
else if (m_CumulativeTime >= 0f)
{
Enter1stStage();
}
}
}
#endregion
#region
public override void InitStuff()
{
base.InitStuff();
m_Type = EventWashingStuffType.UnloadGlass;
m_ConsumeTime = m_LoopTime + m_FinalBlowTime;
StopAction();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d98a4d0b4b3a0104c90f5fa01fe37931
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c489a6fa7c9468e4ea5b8185f338c62a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,419 @@
using CW.Common;
using PaintCore;
using PaintIn3D;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class BHitScreen : BHitScreenBase
{
// This stores extra information for each finger unique to this component
protected class Link : CwInputManager.Link
{
public float Age;
public bool Down;
public int State;
public float Distance;
public Vector2 ScreenDelta;
public Vector2 ScreenOld;
public List<Vector2> History = new List<Vector2>();
public void Move(Vector2 screenNew)
{
if (State == 0)
{
ScreenOld = screenNew;
State = 1;
}
else
{
if (TryMove(screenNew) == true || State == 2)
{
State += 1;
}
}
}
private bool TryMove(Vector2 screenNew)
{
var threshold = 2.0f;
var distance = Vector2.Distance(ScreenOld, screenNew);
if (distance >= threshold)
{
ScreenOld = Vector2.MoveTowards(ScreenOld, screenNew, distance - threshold * 0.5f);
return true;
}
return false;
}
public override void Clear()
{
Age = 0.0f;
Down = false;
State = 0;
Distance = 0.0f;
ScreenDelta = Vector2.zero;
ScreenOld = Vector2.zero;
History.Clear();
}
}
public enum FrequencyType
{
PixelInterval,
ScaledPixelInterval,
TimeInterval,
OnceOnRelease,
OnceOnPress,
OnceEveryFrame
}
/// <summary>This allows you to control how often the screen is painted.
/// PixelInterval = Once every <b>Interval</b> pixels.
/// ScaledPixelInterval = Like <b>PixelInterval</b>, but scaled to the screen DPI.
/// TimeInterval = Once every <b>Interval</b> seconds.
/// OnceOnRelease = When the finger/mouse goes down a preview will be shown, and when it goes up the paint will apply.
/// OnceOnPress = When the finger/mouse goes down the paint will apply.
/// OnceEveryFrame = Every frame the paint will apply.</summary>
public FrequencyType Frequency { set { frequency = value; } get { return frequency; } }
[SerializeField] private FrequencyType frequency = FrequencyType.OnceEveryFrame;
/// <summary>This allows you to set the pixels/seconds between each hit point based on the current <b>Frequency</b> setting.</summary>
public float Interval { set { interval = value; } get { return interval; } }
[SerializeField] private float interval = 10.0f;
/// <summary>This allows you to connect the hit points together to form lines.</summary>
public CwPointConnector Connector { get { if (connector == null) connector = new CwPointConnector(); return connector; } }
[SerializeField] private CwPointConnector connector;
[System.NonSerialized]
private List<Link> links = new List<Link>();
/// <summary>This component sends hit events to a cached list of components that can receive them. If this list changes then you must manually call this method.</summary>
[ContextMenu("Clear Hit Cache")]
public void ClearHitCache()
{
Connector.ClearHitCache();
}
/// <summary>If this GameObject has teleported and you have <b>ConnectHits</b> or <b>HitSpacing</b> enabled, then you can call this to prevent a line being drawn between the previous and current points.</summary>
[ContextMenu("Reset Connections")]
public void ResetConnections()
{
connector.ResetConnections();
}
protected virtual void OnEnable()
{
foreach (var link in links)
{
link.Clear();
}
Connector.ResetConnections();
if (ShouldUpgradePointers() == true)
{
Debug.LogWarning("Upgrading CwHitScreen Controls - To remove this warning you can manually click the \"Upgrade\" button in the inspector of this component while outside of play mode.", gameObject);
TryUpgradePointers();
}
}
protected virtual void Update()
{
connector.Update();
}
public override void BreakFinger(CwInputManager.Finger finger)
{
var link = CwInputManager.Link.Find(links, finger);
if (link != null)
{
connector.BreakHits(link);
}
}
public override void HandleFingerUpdate(CwInputManager.Finger finger, bool down, bool up)
{
var link = CwInputManager.Link.Find(links, finger);
var set = true;
if (finger.Index < 0) // Preview?
{
if (CwInputManager.PointOverGui(finger.ScreenPosition, GuiLayers) == true)
{
connector.BreakHits(link);
return;
}
}
else
{
if (down == true)
{
if (CwInputManager.PointOverGui(finger.ScreenPosition, GuiLayers) == true)
{
connector.BreakHits(link);
return;
}
}
else
{
if (link == null)
{
return;
}
}
}
if (link == null)
{
link = CwInputManager.Link.Create(ref links, finger);
}
link.Move(finger.ScreenPosition);
if (finger.Index < 0) // Preview?
{
RecordAndPaintAt(link, finger.ScreenPosition, link.ScreenOld, true, 0.0f, link);
return;
}
if (NeedsDrawAngle == true)
{
down = link.State == 2;
set = link.State >= 2;
}
if (set == true)
{
switch (frequency)
{
case FrequencyType.PixelInterval: PaintSmooth(link, down, interval); break;
case FrequencyType.ScaledPixelInterval: PaintSmooth(link, down, interval / CwInputManager.ScaleFactor); break;
case FrequencyType.TimeInterval: PaintInterval(link, down); break;
case FrequencyType.OnceOnRelease: PaintRelease(link, up); break;
case FrequencyType.OnceOnPress: PaintPress(link, down); break;
case FrequencyType.OnceEveryFrame: PaintEvery(link, down); break;
}
}
base.HandleFingerUpdate(finger, down, up);
}
protected override void HandleFingerUp(CwInputManager.Finger finger)
{
var link = CwInputManager.Link.Find(links, finger);
if (link != null)
{
connector.BreakHits(link);
OnFingerUp(link);
link.Clear();
}
}
private void PaintSmooth(Link link, bool down, float pixelSpacing)
{
var head = link.Finger.GetSmoothScreenPosition(0.0f);
if (down == true || link.History.Count == 0)
{
if (storeStates == true)
{
CwStateManager.PotentiallyStoreAllStates();
}
RecordAndPaintAt(link, link.Finger.ScreenPosition, link.ScreenOld, false, link.Finger.Pressure, link);
}
if (pixelSpacing > 0.0f)
{
var steps = Mathf.Max(1, Mathf.FloorToInt(link.Finger.SmoothScreenPositionDelta));
var step = CwHelper.Reciprocal(steps);
for (var i = 0; i <= steps; i++)
{
var next = link.Finger.GetSmoothScreenPosition(Mathf.Clamp01(i * step));
var dist = Vector2.Distance(head, next);
var gaps = Mathf.FloorToInt((link.Distance + dist) / pixelSpacing);
for (var j = 0; j < gaps; j++)
{
var remainder = pixelSpacing - link.Distance;
head = Vector2.MoveTowards(head, next, remainder);
RecordAndPaintAt(link, head, link.History[link.History.Count - 1], false, link.Finger.Pressure, link);
dist -= remainder;
link.Distance = 0.0f;
}
link.Distance += dist;
head = next;
}
}
}
protected virtual void OnFingerUp(Link link)
{
}
private void PaintInterval(Link link, bool down)
{
if (down == true)
{
if (storeStates == true)
{
CwStateManager.PotentiallyStoreAllStates();
}
link.Age = interval;
}
link.Age += Time.deltaTime;
if (link.Age >= interval)
{
if (interval > 0.0f)
{
link.Age %= interval;
}
else
{
link.Age = 0.0f;
}
RecordAndPaintAt(link, link.Finger.ScreenPosition, link.ScreenOld, false, link.Finger.Pressure, link);
}
}
private void PaintRelease(Link link, bool up)
{
var preview = true;
if (up == true)
{
preview = false;
if (storeStates == true)
{
CwStateManager.PotentiallyStoreAllStates();
}
}
RecordAndPaintAt(link, link.Finger.ScreenPosition, link.ScreenOld, preview, link.Finger.Pressure, link);
}
private void PaintPress(Link link, bool down)
{
if (down == true)
{
if (storeStates == true)
{
CwStateManager.PotentiallyStoreAllStates();
}
RecordAndPaintAt(link, link.Finger.ScreenPosition, link.ScreenOld, false, link.Finger.Pressure, link);
}
}
private void PaintEvery(Link link, bool down)
{
if (down == true)
{
if (storeStates == true)
{
CwStateManager.PotentiallyStoreAllStates();
}
}
RecordAndPaintAt(link, link.Finger.ScreenPosition, link.ScreenOld, false, link.Finger.Pressure, link);
}
private void RecordAndPaintAt(Link link, Vector2 screenNew, Vector2 screenOld, bool preview, float pressure, object owner)
{
link.History.Add(screenNew);
PaintAt(connector, connector.HitCache, screenNew, screenOld, preview, pressure, owner);
}
}
}
#if UNITY_EDITOR
namespace game
{
using UnityEditor;
using TARGET = BHitScreen;
[CanEditMultipleObjects]
[CustomEditor(typeof(TARGET))]
public class BHitScreen_Editor : CwHitScreenBase_Editor
{
protected override void OnInspector()
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
base.OnInspector();
Separator();
DrawBasic();
Separator();
DrawAdvancedFoldout();
Separator();
var point = tgt.Emit == BHitScreenBase.EmitType.PointsIn3D;
var line = tgt.Emit == BHitScreenBase.EmitType.PointsIn3D && tgt.Connector.ConnectHits == true;
var triangle = tgt.Emit == BHitScreenBase.EmitType.TrianglesIn3D;
var coord = tgt.Emit == BHitScreenBase.EmitType.PointsOnUV;
tgt.Connector.HitCache.Inspector(tgt.gameObject, point: point, line: line, triangle: triangle, coord: coord);
}
protected override void DrawBasic()
{
TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts);
base.DrawBasic();
Draw("frequency", "This allows you to control how often the screen is painted.\n\nPixelInterval = Once every Interval pixels.\n\nScaledPixelInterval = Once every Interval scaled pixels.\n\nTimeInterval = Once every Interval seconds.\n\nOnceOnRelease = When the finger/mouse goes down a preview will be shown, and when it goes up the paint will apply.\n\nOnceOnPress = When the finger/mouse goes down the paint will apply.\n\nOnceEveryFrame = Every frame the paint will apply.");
if (Any(tgts, t => t.Frequency == BHitScreen.FrequencyType.PixelInterval || t.Frequency == BHitScreen.FrequencyType.ScaledPixelInterval || t.Frequency == BHitScreen.FrequencyType.TimeInterval))
{
BeginIndent();
BeginError(Any(tgts, t => t.Interval <= 0.0f));
Draw("interval", "This allows you to set the pixels/seconds between each hit point based on the current Frequency setting.");
EndError();
EndIndent();
}
}
protected override void DrawAdvanced()
{
base.DrawAdvanced();
Separator();
CwPointConnector_Editor.Draw();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 623b6c15fb081f3408bd04cbf9b5e520
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,360 @@
using CW.Common;
using PaintCore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
/// <summary>This class contains common code for screen based mouse/finger hit components.</summary>
public abstract class BHitScreenBase : CwHitPointers
{
public enum RotationType
{
Normal,
World,
ThisRotation,
ThisLocalRotation,
CustomRotation,
CustomLocalRotation
}
public enum RelativeType
{
WorldUp,
CameraUp,
DrawAngle
}
public enum DirectionType
{
HitNormal,
RayDirection,
CameraDirection
}
public enum EmitType
{
PointsIn3D = 0,
PointsOnUV = 20,
TrianglesIn3D = 30
}
[System.Flags]
public enum ButtonTypes
{
LeftMouse = 1 << 0,
RightMouse = 1 << 1,
MiddleMouse = 1 << 2,
Touch = 1 << 5
}
/// <summary>Orient to a specific camera?
/// None = MainCamera.</summary>
public Camera Camera { set { _camera = value; } get { return _camera; } }
[SerializeField] private Camera _camera;
/// <summary>The layers you want the raycast to hit.</summary>
public LayerMask Layers { set { layers = value; } get { return layers; } }
[SerializeField] private LayerMask layers = Physics.DefaultRaycastLayers;
/// <summary>This allows you to control the hit data this component sends out.
/// PointsIn3D = Point drawing in 3D.
/// PointsOnUV = Point drawing on UV (requires non-convex <b>MeshCollider</b>).
/// TrianglesIn3D = Triangle drawing in 3D (requires non-convex <b>MeshCollider</b>).</summary>
public EmitType Emit { set { emit = value; } get { return emit; } }
[UnityEngine.Serialization.FormerlySerializedAs("draw")][SerializeField] private EmitType emit;
/// <summary>This allows you to control how the paint is rotated.
/// Normal = The rotation will be based on a normal direction, and rolled relative to an up axis.
/// World = The rotation will be aligned to the world, or given no rotation.
/// ThisRotation = The current <b>Transform.rotation</b> will be used.
/// ThisLocalRotation = The current <b>Transform.localRotation</b> will be used.
/// CustomRotation = The specified <b>CustomTransform.rotation</b> will be used.
/// CustomLocalRotation = The specified <b>CustomTransform.localRotation</b> will be used.</summary>
public RotationType RotateTo { set { rotateTo = value; } get { return rotateTo; } }
[SerializeField] private RotationType rotateTo;
/// <summary>Which direction should the hit point rotation be based on?</summary>
public DirectionType NormalDirection { set { normalDirection = value; } get { return normalDirection; } }
[UnityEngine.Serialization.FormerlySerializedAs("normal")][SerializeField] private DirectionType normalDirection = DirectionType.CameraDirection;
/// <summary>Based on the normal direction, what should the rotation be rolled relative to?
/// WorldUp = It will be rolled so the up vector is world up.
/// CameraUp = It will be rolled so the up vector is camera up.
/// DrawAngle = It will be rolled according to the mouse/finger movement on screen.</summary>
public RelativeType NormalRelativeTo { set { normalRelativeTo = value; } get { return normalRelativeTo; } }
[UnityEngine.Serialization.FormerlySerializedAs("orientation")][SerializeField] private RelativeType normalRelativeTo = RelativeType.CameraUp;
/// <summary>This allows you to specify the <b>Transform</b> when using <b>RotateTo = CustomRotation/CustomLocalRotation</b>.</summary>
public Transform CustomTransform { set { customTransform = value; } get { return customTransform; } }
[SerializeField] private Transform customTransform;
/// <summary>Should painting triggered from this component be eligible for being undone?</summary>
public bool StoreStates { set { storeStates = value; } get { return storeStates; } }
[SerializeField] protected bool storeStates = true;
/// <summary>This allows you to override the order this paint gets applied to the object during the current frame.</summary>
public int Priority { set { priority = value; } get { return priority; } }
[SerializeField] private int priority;
/// <summary>If you want the raycast hit point to be offset from the surface a bit, this allows you to set by how much in world space.</summary>
public float NormalOffset { set { normalOffset = value; } get { return normalOffset; } }
[SerializeField] private float normalOffset;
// No longer used
[SerializeField] private ButtonTypes requiredButtons;
// No longer used
[SerializeField] private KeyCode requiredKey;
// No longer used
[SerializeField] private float mouseOffset;
// No longer used
[SerializeField] private float touchOffset;
// No longer used
[SerializeField] private bool showPreview;
private static Transform m_TargetTransform = null;
public static void SetTargetTransform(Transform targetTransform)
{
m_TargetTransform = targetTransform;
}
public bool NeedsDrawAngle
{
get
{
return rotateTo == RotationType.Normal && normalRelativeTo == RelativeType.DrawAngle;
}
}
private bool m_IsAuthorizedDrawing = false;
public void AuthorizedDrawing()
{
m_IsAuthorizedDrawing = true;
}
public void NotAuthorizedDrawing()
{
m_IsAuthorizedDrawing = false;
}
#if UNITY_EDITOR
protected virtual void Reset()
{
if (GetComponent<CwPointerMouse>() == null)
{
requiredButtons &= ~ButtonTypes.LeftMouse;
requiredButtons &= ~ButtonTypes.RightMouse;
requiredButtons &= ~ButtonTypes.MiddleMouse;
gameObject.AddComponent<CwPointerMouse>();
}
if (GetComponent<CwPointerTouch>() == null)
{
requiredButtons &= ~ButtonTypes.Touch;
gameObject.AddComponent<CwPointerTouch>();
}
if (GetComponent<CwPointerPen>() == null)
{
gameObject.AddComponent<CwPointerPen>();
}
}
#endif
public bool ShouldUpgradePointers()
{
return (requiredButtons & ButtonTypes.LeftMouse) != 0
|| (requiredButtons & ButtonTypes.RightMouse) != 0
|| (requiredButtons & ButtonTypes.MiddleMouse) != 0
|| (requiredButtons & ButtonTypes.Touch) != 0;
}
public void TryUpgradePointers()
{
var lmb = (requiredButtons & ButtonTypes.LeftMouse) != 0;
var rmb = (requiredButtons & ButtonTypes.RightMouse) != 0;
var mmb = (requiredButtons & ButtonTypes.MiddleMouse) != 0;
if (lmb == true || rmb == true || mmb == true)
{
requiredButtons &= ~ButtonTypes.LeftMouse;
requiredButtons &= ~ButtonTypes.RightMouse;
requiredButtons &= ~ButtonTypes.MiddleMouse;
var pointerMouse = gameObject.AddComponent<CwPointerMouse>();
pointerMouse.Preview = showPreview;
if (lmb == true)
{
pointerMouse.TryAddKey(KeyCode.Mouse0);
}
if (rmb == true)
{
pointerMouse.TryAddKey(KeyCode.Mouse1);
}
if (mmb == true)
{
pointerMouse.TryAddKey(KeyCode.Mouse2);
}
}
if ((requiredButtons & ButtonTypes.Touch) != 0)
{
requiredButtons &= ~ButtonTypes.Touch;
var pointerTouch = gameObject.AddComponent<CwPointerTouch>();
pointerTouch.Offset = touchOffset;
}
}
protected virtual void DoQuery(Vector2 screenPosition, ref Camera camera, ref Ray ray, ref CwHit hit3D, ref RaycastHit2D hit2D)
{
var hit = default(RaycastHit);
camera = CwHelper.GetCamera(_camera);
ray = camera.ScreenPointToRay(screenPosition);
hit2D = Physics2D.GetRayIntersection(ray, float.PositiveInfinity, layers);
Physics.Raycast(ray, out hit, float.PositiveInfinity, layers);
hit3D = new CwHit(hit);
}
protected void PaintAt(CwPointConnector connector, CwHitCache hitCache, Vector2 screenPosition, Vector2 screenPositionOld, bool preview, float pressure, object owner)
{
var camera = default(Camera);
var ray = default(Ray);
var hit2D = default(RaycastHit2D);
var hit3D = default(CwHit);
var finalPosition = default(Vector3);
var finalRotation = default(Quaternion);
DoQuery(screenPosition, ref camera, ref ray, ref hit3D, ref hit2D);
var valid2D = hit2D.distance > 0.0f;
var valid3D = hit3D.Distance > 0.0f;
// Hit 3D?
if (valid3D == true && (valid2D == false || hit3D.Distance < hit2D.distance))
{
CalcHitData(hit3D.Position, hit3D.Normal, ray, camera, screenPositionOld, ref finalPosition, ref finalRotation);
if (emit == EmitType.PointsIn3D)
{
if (connector != null)
{
if (m_TargetTransform != null && hit3D.Transform != m_TargetTransform) { return; }
if (m_IsAuthorizedDrawing)
{
connector.SubmitPoint(gameObject, preview, priority, pressure, finalPosition, finalRotation, owner);
}
FishingYachtAct.Publish<EventWashingCleanerFollowPositionData>(new EventWashingCleanerFollowPositionData(finalPosition, hit3D.Normal));
}
else
{
hitCache.InvokePoint(gameObject, preview, priority, pressure, finalPosition, finalRotation);
}
return;
}
else if (emit == EmitType.PointsOnUV)
{
hitCache.InvokeCoord(gameObject, preview, priority, pressure, hit3D, finalRotation);
return;
}
else if (emit == EmitType.TrianglesIn3D)
{
hitCache.InvokeTriangle(gameObject, preview, priority, pressure, hit3D, finalRotation);
return;
}
}
// Hit 2D?
else if (valid2D == true)
{
CalcHitData(hit2D.point, new Vector3(0.0f, 0.0f, -1.0f), ray, camera, screenPositionOld, ref finalPosition, ref finalRotation);
if (emit == EmitType.PointsIn3D)
{
if (connector != null)
{
connector.SubmitPoint(gameObject, preview, priority, pressure, finalPosition, finalRotation, owner);
}
else
{
hitCache.InvokePoint(gameObject, preview, priority, pressure, finalPosition, finalRotation);
}
return;
}
}
if (connector != null)
{
connector.BreakHits(owner);
}
}
private void CalcHitData(Vector3 hitPoint, Vector3 hitNormal, Ray ray, Camera camera, Vector2 screenPositionOld, ref Vector3 finalPosition, ref Quaternion finalRotation)
{
finalPosition = hitPoint + hitNormal * normalOffset;
finalRotation = Quaternion.identity;
switch (rotateTo)
{
case RotationType.Normal:
{
var finalNormal = default(Vector3);
switch (normalDirection)
{
case DirectionType.HitNormal: finalNormal = hitNormal; break;
case DirectionType.RayDirection: finalNormal = -ray.direction; break;
case DirectionType.CameraDirection: finalNormal = -camera.transform.forward; break;
}
var finalUp = Vector3.up;
switch (normalRelativeTo)
{
case RelativeType.CameraUp: finalUp = camera.transform.up; break;
case RelativeType.DrawAngle:
{
var rayOld = camera.ScreenPointToRay(screenPositionOld);
if (camera.orthographic == true)
{
finalUp = Vector3.Cross(rayOld.GetPoint(1.0f) - ray.origin, ray.GetPoint(1.0f) - ray.origin);
}
else
{
finalUp = Vector3.Cross(rayOld.direction, ray.direction);
}
}
break;
}
finalRotation = Quaternion.LookRotation(-finalNormal, finalUp);
}
break;
case RotationType.World: finalRotation = Quaternion.identity; break;
case RotationType.ThisRotation: finalRotation = transform.rotation; break;
case RotationType.ThisLocalRotation: finalRotation = transform.localRotation; break;
case RotationType.CustomRotation: if (customTransform != null) finalRotation = customTransform.rotation; break;
case RotationType.CustomLocalRotation: if (customTransform != null) finalRotation = customTransform.localRotation; break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ed4ded6cb8412cd49ad4d1b9ed2a5678
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,105 @@
using PaintCore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace game
{
/// <summary>This component fills the attached UI Image based on the total amount of opaque pixels that have been painted in all active and enabled <b>CwChannelCounter</b> components in the scene.</summary>
[RequireComponent(typeof(Image))]
public class BrushChannelCounterFill : MonoBehaviour
{
public enum ChannelType
{
Red,
Green,
Blue,
Alpha
}
/// <summary>This allows you to specify the counters that will be used.
/// Zero = All active and enabled counters in the scene.</summary>
public List<CwChannelCounter> Counters { get { if (counters == null) counters = new List<CwChannelCounter>(); return counters; } }
[SerializeField] private List<CwChannelCounter> counters;
/// <summary>This allows you to choose which channel will be output to the UI Image.</summary>
public ChannelType Channel { set { channel = value; } get { return channel; } }
[SerializeField] private ChannelType channel;
/// <summary>Inverse the fill?</summary>
public bool Inverse { set { inverse = value; } get { return inverse; } }
[SerializeField] private bool inverse;
private static float m_OmitPercentage = 0.1f;
public static float OmitPercentage { get => m_OmitPercentage; set => m_OmitPercentage = value; }
private bool m_IsOver = false;
[System.NonSerialized]
private Image cachedImage;
private bool m_IsStopping = false;
public void ResetData()
{
m_IsOver = false;
}
public void StopCounting()
{
m_IsStopping = true;
}
public void StartCounting()
{
m_IsStopping = false;
}
protected virtual void OnEnable()
{
cachedImage = GetComponent<Image>();
m_IsOver = false;
}
protected virtual void Update()
{
if (m_IsStopping) return;
var finalCounters = counters.Count > 0 ? counters : null;
var ratio = 0.0f;
switch (channel)
{
case ChannelType.Red: ratio = CwChannelCounter.GetRatioR(finalCounters); break;
case ChannelType.Green: ratio = CwChannelCounter.GetRatioG(finalCounters); break;
case ChannelType.Blue: ratio = CwChannelCounter.GetRatioB(finalCounters); break;
case ChannelType.Alpha: ratio = CwChannelCounter.GetRatioA(finalCounters); break;
}
if (inverse == true)
{
ratio = 1.0f - ratio;
}
FishingYachtAct.Publish<EventWashingMonitoringFoamProgressData>(new EventWashingMonitoringFoamProgressData(ratio));
if (1 - ratio <= BrushChannelCounterFill.m_OmitPercentage)
{
if (m_IsOver == false)
{
FishingYachtAct.Publish<EventWashingConclusionData>(new EventWashingConclusionData());
m_IsOver = true;
}
cachedImage.fillAmount = 1.0f;
}
else
{
float tmp = 1f - BrushChannelCounterFill.m_OmitPercentage;
float realProgress = ratio / tmp;
cachedImage.fillAmount = Mathf.Clamp01(realProgress);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8fdfd5b58cbf79143a8b9f55919fe9b5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
using CW.Common;
using PaintCore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace game
{
[RequireComponent(typeof(CwHitPointers))]
public class BrushPointerMouse : CwPointer
{
public Vector2 Offset { set { offset = value; } get { return offset; } }
[SerializeField] private Vector2 offset = Vector2.zero;
/// <summary>If you enable this, then a paint preview will be shown under the mouse as long as the <b>RequiredKey</b> is not pressed.</summary>
public bool Preview { set { preview = value; } get { return preview; } }
[SerializeField] private bool preview;
/// <summary>This component will paint while any of the specified mouse buttons or keyboard keys are held.</summary>
public List<KeyCode> Keys { get { if (keys == null) { keys = new List<KeyCode>(); } return keys; } }
[SerializeField] private List<KeyCode> keys;
private readonly int PREVIEW_FINGER_INDEX = -1;
private readonly int PAINT_FINGER_INDEX = 1;
[System.NonSerialized]
private bool oldHeld;
public bool TryAddKey(KeyCode key)
{
if (Keys.Contains(key) == false)
{
keys.Add(key);
return true;
}
return false;
}
public bool GetKeyHeld()
{
if (keys != null)
{
foreach (var key in keys)
{
if (CwInput.GetKeyIsHeld(key) == true)
{
return true;
}
}
}
return false;
}
#if UNITY_EDITOR
protected virtual void Reset()
{
if (keys == null)
{
keys = new List<KeyCode>();
}
else
{
keys.Clear();
}
keys.Add(KeyCode.Mouse0);
}
#endif
protected virtual void Update()
{
var newHeld = false;
var enablePreview = false;
var enablePaint = false;
bool isFollowing = false;
Vector2 screenPosition = Vector2.zero;
if (CwInput.GetMouseExists() == true)
{
CwInputManager.Finger finger;
newHeld = GetKeyHeld();
enablePaint = newHeld == true || oldHeld == true;
enablePreview = preview == true && enablePaint == false;
Vector2 position = CwInput.GetMousePosition();
position += offset * CwInputManager.ScaleFactor;
if (enablePreview == true)
{
GetFinger(PREVIEW_FINGER_INDEX, position, 1.0f, true, out finger);
cachedHitPointers.HandleFingerUpdate(finger, false, false);
screenPosition = position;
isFollowing = true;
}
if (enablePaint == true)
{
if (EventSystem.current == null) return;
if (EventSystem.current.IsPointerOverGameObject()) return;
var down = GetFinger(PAINT_FINGER_INDEX, position, 1.0f, true, out finger);
cachedHitPointers.HandleFingerUpdate(finger, down, newHeld == false);
screenPosition = position;
isFollowing = true;
}
}
if (isFollowing) FishingYachtAct.Publish<EventWashingGestureFollowPositionData>(new EventWashingGestureFollowPositionData(screenPosition, true));
else FishingYachtAct.Publish<EventWashingGestureFollowPositionData>(new EventWashingGestureFollowPositionData(screenPosition, false));
if (enablePreview == false)
{
TryNullFinger(PREVIEW_FINGER_INDEX);
}
if (enablePaint == false)
{
TryNullFinger(PAINT_FINGER_INDEX);
}
oldHeld = newHeld;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a76738f841592a4fb2fded5869f4534
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using CW.Common;
using PaintCore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace game
{
[RequireComponent(typeof(CwHitPointers))]
public class BrushPointerTouch : CwPointer
{
/// <summary>If you want the paint to appear above the finger, then you can set this number to something positive.</summary>
public Vector2 Offset { set { offset = value; } get { return offset; } }
[SerializeField] private Vector2 offset = Vector2.zero;
protected virtual void Update()
{
CwInputManager.Finger finger;
bool isFollowing = false;
Vector2 screenPosition = Vector2.zero;
for (var i = 0; i < CwInput.GetTouchCount(); i++)
{
int index;
Vector2 position;
float pressure;
bool set;
if (EventSystem.current == null) return;
if (EventSystem.current.IsPointerOverGameObject()) return;
CwInput.GetTouch(i, out index, out position, out pressure, out set);
position += offset * CwInputManager.ScaleFactor;
var down = GetFinger(index, position, pressure, set, out finger);
cachedHitPointers.HandleFingerUpdate(finger, down, set == false);
screenPosition = position;
isFollowing = true;
if (set == false)
{
TryNullFinger(index);
}
}
if (isFollowing) FishingYachtAct.Publish<EventWashingGestureFollowPositionData>(new EventWashingGestureFollowPositionData(screenPosition, true));
else FishingYachtAct.Publish<EventWashingGestureFollowPositionData>(new EventWashingGestureFollowPositionData(screenPosition, false));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bb3ec75e2f551f248a6e890b43a4be89
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,358 @@
using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace game
{
[ExecuteAlways]
[DisallowMultipleComponent]
public class CameraFollowPathMoveController : MonoBehaviour
{
/// <summary>The path to follow</summary>
[Tooltip("The path to follow")]
public CinemachinePath Path;
[Tooltip("路径停歇点索引,循环执行。eg:5个点执行到最后一个位置会从移动到初始位置开始。")]
public List<int> m_RestIndexList = new List<int>();
[Tooltip("磁性距离,距离目标点一定距离,即认为到达目标点。")]
public float m_MagneticDistance = 0.01f;
[Tooltip("一直移动,可以查看整个移动过程,主要用于本地测试。发包时关闭。")]
public bool IsAlwaysMoving = false;
[Tooltip("是否开启测试停歇点配合TestRestIndex使用主要用于本地测试。发包时关闭。")]
public bool m_IsTestRest = false;
[Tooltip("测试用停歇点索引配合IsTestRest使用默认为-1,在0-停歇点索引位之间生效。")]
public int m_TestRestIndex = -1;
/// <summary>This enum defines the options available for the update method.</summary>
public enum UpdateMethod
{
/// <summary>Updated in normal MonoBehaviour Update.</summary>
Update,
/// <summary>Updated in sync with the Physics module, in FixedUpdate</summary>
FixedUpdate,
/// <summary>Updated in normal MonoBehaviour LateUpdate</summary>
LateUpdate
};
/// <summary>When to move the cart, if Velocity is non-zero</summary>
[Tooltip("When to move the cart, if Velocity is non-zero")]
public UpdateMethod m_UpdateMethod = UpdateMethod.Update;
/// <summary>How to interpret the Path Position</summary>
[Tooltip("How to interpret the Path Position. If set to Path Units, values are as follows: 0 represents the first waypoint on the path, 1 is the second, and so on. Values in-between are points on the path in between the waypoints. If set to Distance, then Path Position represents distance along the path.")]
[HideInInspector] public CinemachinePathBase.PositionUnits m_PositionUnits = CinemachinePathBase.PositionUnits.Distance;
/// <summary>Move the cart with this speed</summary>
[Tooltip("Move the cart with this speed along the path. The value is interpreted according to the Position Units setting.")]
[FormerlySerializedAs("m_Velocity")]
public float Speed;
/// <summary>The cart's current position on the path, in distance units</summary>
[Tooltip("The position along the path at which the cart will be placed. This can be animated directly or, if the velocity is non-zero, will be updated automatically. The value is interpreted according to the Position Units setting.")]
[FormerlySerializedAs("m_CurrentDistance")]
[HideInInspector] public float m_Position;
private enum MoveState
{
Stationary,
Moving
}
private MoveState m_State = MoveState.Stationary;
private int m_MoveIndex = 0;
private int m_CurPathIndex = 0;
//private int m_MoveDirection = 0;
void Awake()
{
#if UNITY_EDITOR
if (Path != null)
{
ResamplePath();
JumpToRestIndex(0);
SetCartPosition(0f);
}
#endif
}
void FixedUpdate()
{
if (m_State == MoveState.Stationary && !IsAlwaysMoving) return;
if (m_UpdateMethod == UpdateMethod.FixedUpdate)
SetCartPosition(m_Position + Speed * Time.deltaTime);
}
void Update()
{
CheckTestRest();
if (m_State == MoveState.Stationary && !IsAlwaysMoving) return;
float speed = Application.isPlaying ? Speed : 0;
if (m_UpdateMethod == UpdateMethod.Update)
SetCartPosition(m_Position + speed * Time.deltaTime);
}
void LateUpdate()
{
if (m_State == MoveState.Stationary && !IsAlwaysMoving) return;
if (!Application.isPlaying)
SetCartPosition(m_Position);
else if (m_UpdateMethod == UpdateMethod.LateUpdate)
SetCartPosition(m_Position + Speed * Time.deltaTime);
}
public void ResetAndInit(CinemachinePath followPath, List<int> restIndexList, float magneticDistance)
{
if (followPath == null || restIndexList == null) return;
if (Path)
{
Path = null;
}
if (m_RestIndexList != null)
{
m_RestIndexList = null;
}
m_MagneticDistance = magneticDistance;
Path = followPath;
m_RestIndexList = restIndexList;
ResamplePath();
}
void SetCartPosition(float distanceAlongPath)
{
if (Path != null)
{
m_Position = Path.StandardizeUnit(distanceAlongPath, m_PositionUnits);
if (!IsAlwaysMoving) m_Position = CheckPosition(distanceAlongPath, m_Position);
transform.position = Path.EvaluatePositionAtUnit(m_Position, m_PositionUnits);
transform.rotation = Path.EvaluateOrientationAtUnit(m_Position, m_PositionUnits);
}
}
private void CheckTestRest()
{
if (m_IsTestRest)
{
if (m_TestRestIndex >= 0 && m_TestRestIndex < m_RestIndexList.Count)
{
m_MoveIndex = m_TestRestIndex;
if (!IsEffective()) return;
GoToPositionIndex(m_RestIndexList[m_MoveIndex]);
}
}
}
List<Vector3[]> m_RestPointDistance = new List<Vector3[]>();
private void ResamplePath()
{
int stepsPerSegment = Path.DistanceCacheSampleStepsPerSegment;
float minPos = Path.MinPos;
float maxPos = Path.MaxPos;
float stepSize = 1f / Mathf.Max(1, stepsPerSegment);
// Sample the positions
int numKeys = Mathf.RoundToInt((maxPos - minPos) / stepSize) + 1;
float[] m_PosToDistance = new float[numKeys];
m_RestPointDistance.Clear();
Vector3[] firstRestDistance = new Vector3[2];
Vector3 firstDest = new Vector3(-m_MagneticDistance, 0f, m_MagneticDistance);
firstRestDistance[0] = firstDest;
m_RestPointDistance.Add(firstRestDistance);
int index = 0;
float m_PathLength = 0f;
Vector3 p0 = Path.EvaluatePosition(0);
m_PosToDistance[0] = 0;
float pos = minPos;
for (int i = 1; i < numKeys; ++i)
{
pos += stepSize;
Vector3 p = Path.EvaluatePosition(pos);
float d = Vector3.Distance(p0, p);
m_PathLength += d;
p0 = p;
m_PosToDistance[i] = m_PathLength;
if (i % stepsPerSegment == 0)
{
Vector3[] tmpArr = new Vector3[1];
Vector3 tmp = new Vector3(m_PathLength - m_MagneticDistance, m_PathLength, m_PathLength + m_MagneticDistance);
tmpArr[0] = tmp;
m_RestPointDistance.Add(tmpArr);
++index;
}
}
if (Path.Looped)
m_RestPointDistance.RemoveAt(index);
Vector3 lastDest = new Vector3(m_PathLength - m_MagneticDistance, m_PathLength, m_PathLength + m_MagneticDistance);
firstRestDistance[1] = lastDest;
}
private bool IsEffective()
{
return (m_MoveIndex >= 0 && m_MoveIndex < m_RestIndexList.Count && m_RestIndexList.Count > 0) ? true : false;
}
public int RestCount
{
get
{
if (m_RestIndexList == null) return 0;
return m_RestIndexList.Count;
}
}
public int MoveIndex
{
get => m_MoveIndex;
}
public int ForwardToNextRest()
{
m_MoveIndex++;
if (m_MoveIndex > m_RestIndexList.Count - 1)
{
if (Path.Looped)
m_MoveIndex = 0;
else
m_MoveIndex = m_RestIndexList.Count - 1;
}
GoToPositionIndex(m_RestIndexList[m_MoveIndex]);
if (Speed < 0)
{
Speed = -Speed;
}
return m_MoveIndex;
}
public int BackwardToNextRest()
{
m_MoveIndex--;
if (m_MoveIndex < 0)
{
if (Path.Looped)
m_MoveIndex = m_RestIndexList.Count - 1;
else
m_MoveIndex = 0;
}
GoToPositionIndex(m_RestIndexList[m_MoveIndex]);
if (Speed > 0)
{
Speed = -Speed;
}
return m_MoveIndex;
}
public int JumpToNextRestForward()
{
JumpToRestIndex(++m_MoveIndex);
return m_MoveIndex;
}
public int JumpToNextRestBackward()
{
JumpToRestIndex(--m_MoveIndex);
return m_MoveIndex;
}
public int JumpToRestIndex(int index)
{
m_MoveIndex = index;
if (m_MoveIndex < 0)
{
if (Path.Looped)
m_MoveIndex = m_RestIndexList.Count - 1;
else
m_MoveIndex = 0;
}
else if (m_MoveIndex > m_RestIndexList.Count - 1)
{
if (Path.Looped)
m_MoveIndex = 0;
else
m_MoveIndex = m_RestIndexList.Count - 1;
}
GoToPositionIndex(m_RestIndexList[m_MoveIndex]);
var tmpArr = m_RestPointDistance[m_CurPathIndex];
Vector3 boundary = tmpArr[0];
float distanceAlongPath = boundary.y;
m_Position = Path.StandardizeUnit(distanceAlongPath, m_PositionUnits);
SetCartPosition(m_Position);
m_State = MoveState.Stationary;
return m_MoveIndex;
}
public void GoToPositionIndex(int index)
{
m_CurPathIndex = index;
m_State = MoveState.Moving;
}
float CheckPosition(float distanceAlongPath, float distance)
{
if (m_CurPathIndex < 0 || m_CurPathIndex >= m_RestPointDistance.Count) return distance;
var tmpArr = m_RestPointDistance[m_CurPathIndex];
int count = tmpArr.Length;
if (count == 0) return distance;
if (m_CurPathIndex == 0)
{
if (Speed > 0f)
{
if (distanceAlongPath >= Path.PathLength)
{
m_State = MoveState.Stationary;
m_IsTestRest = false;
FishingYachtAct.Publish<EventWashingCameraStopData>(new EventWashingCameraStopData());
return tmpArr[0].y;
}
}
else if (Speed < 0f)
{
if (distanceAlongPath <= 0f)
{
m_State = MoveState.Stationary;
m_IsTestRest = false;
FishingYachtAct.Publish<EventWashingCameraStopData>(new EventWashingCameraStopData());
return tmpArr[0].y;
}
}
}
else
{
if (Speed > 0f)
{
if (distance >= tmpArr[0].x)
{
m_State = MoveState.Stationary;
m_IsTestRest = false;
FishingYachtAct.Publish<EventWashingCameraStopData>(new EventWashingCameraStopData());
return tmpArr[0].y;
}
}
else if (Speed <= 0f)
{
if (distance <= tmpArr[0].z)
{
m_State = MoveState.Stationary;
m_IsTestRest = false;
FishingYachtAct.Publish<EventWashingCameraStopData>(new EventWashingCameraStopData());
return tmpArr[0].y;
}
}
}
return distance;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 425c3dabfac452a4e9fd1c91aa086545
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,241 @@
using cfg;
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace game
{
public class OperatingToolsBase : MonoBehaviour
{
[Tooltip("工具ID")]
public int m_ID = 0;
[Tooltip("工具操作前的准备时间,常用于移到指定位置等。")]
public float m_PreparationTime = 0.1f;
//[Tooltip("初始Transform")]
[HideInInspector] public Transform InitTransfom;
#region Transform变换相关
/// <summary>
/// 跳转到展示区(即初始Transform : m_InitTransfom)
/// </summary>
public void JumpToExhibition()
{
if (InitTransfom is null) return;
this.transform.parent = InitTransfom.parent;
this.transform.SetParent(InitTransfom.parent, false);
this.transform.localScale = InitTransfom.localScale;
this.transform.rotation = InitTransfom.rotation;
this.transform.position = InitTransfom.position;
}
/// <summary>
/// 移动到指定 Transform
/// </summary>
/// <param name="transform"></param>
public void MoveToTransform(Transform transform)
{
if (transform is null) return;
this.transform.DOKill();
this.transform.DOMove(transform.position, m_PreparationTime).SetEase(Ease.OutQuad);
this.transform.DOScale(transform.localScale, m_PreparationTime).SetEase(Ease.Linear);
this.transform.DORotateQuaternion(transform.rotation, m_PreparationTime).SetEase(Ease.Linear);
}
/// <summary>
/// 返回到展示区(即初始Transform : m_InitTransfom)
/// </summary>
public virtual void MoveToExhibition()
{
// 停止播放操作动画
StopPlayOperationAnimation();
// 停止播放准备动画
StopPlayPrepareAnimation();
if (InitTransfom == null) return;
MoveToTransform(InitTransfom);
m_Status = EventWashingActionStatus.Invalid;
}
#endregion
#region
protected bool m_IsAuthorizedAnimation = true;
public bool IsAuthorizedAnimation { get => m_IsAuthorizedAnimation; }
public void AuthorizedAnimation()
{
m_IsAuthorizedAnimation = true;
}
public void NotAuthorizedAnimation()
{
m_IsAuthorizedAnimation = false;
}
/// <summary>
/// 播放工具操作动画
/// </summary>
protected virtual void PlayOperationAnimation()
{
}
/// <summary>
/// 停止播放工具操作动画
/// </summary>
protected virtual void StopPlayOperationAnimation()
{
}
/// <summary>
/// 播放准备动画
/// </summary>
protected virtual void PlayPrepareAnimation()
{
}
/// <summary>
/// 停止播放准备动画
/// </summary>
protected virtual void StopPlayPrepareAnimation()
{
}
#endregion
#region
/// <summary>
/// 开始工具操作行为
/// </summary>
/// <param name="overAction"></param>
public virtual void StartExecuting()
{
m_Status = EventWashingActionStatus.Executing;
m_PrepareCumulativeTime = 0f;
// 播放操作动画
if (m_IsAuthorizedAnimation) PlayOperationAnimation();
}
/// <summary>
/// 操作前的准备行为,如:移动等
/// </summary>
/// <param name="args"></param>
public void PrepareAction(Transform transform, UnityAction<OperatingToolsBase> readyAction, params object[] args)
{
m_Status = EventWashingActionStatus.Preparing;
m_PrepareCumulativeTime = 0f;
m_ReadyAction = readyAction;
MoveToTransform(transform);
if (m_IsAuthorizedAnimation) PlayPrepareAnimation();
}
/// <summary>
/// 停止操作行为
/// </summary>
public virtual void StopExecuting()
{
if (m_Status == EventWashingActionStatus.Executing)
{
MoveToExhibition();
StopPlayOperationAnimation();
}
m_Status = EventWashingActionStatus.Stopping;
}
public virtual void Enter1stStage()
{
}
public virtual void Exit1stStage()
{
}
public virtual void Enter2ndStage()
{
}
public virtual void Exit2ndStage()
{
}
#endregion
#region
/// <summary>
/// 准备结束事件
/// </summary>
UnityAction<OperatingToolsBase> m_ReadyAction = null;
#endregion
#region &
/// <summary>
/// 状态
/// </summary>
protected EventWashingActionStatus m_Status = EventWashingActionStatus.Invalid;
public EventWashingActionStatus Status
{
get { return m_Status; }
}
/// <summary>
/// 准备操作累计时间,用以本地计时
/// </summary>
protected float m_PrepareCumulativeTime = 0f;
protected EventWashingTool m_Type = EventWashingTool.None; // 工具类型
public EventWashingTool ToolType { get { return m_Type; } }
public int ToolID { get { return m_ID; } }
#endregion
#region
/// <summary>
/// 初始化工具
/// </summary>
public virtual void InitTool()
{
m_Type = EventWashingTool.None;
m_PrepareCumulativeTime = 0f;
m_Status = EventWashingActionStatus.Invalid;
JumpToExhibition();
this.gameObject.SetActive(false);
}
// Start is called before the first frame update
protected virtual void Start()
{
m_PrepareCumulativeTime = 0f;
m_Status = EventWashingActionStatus.Invalid;
}
// Update is called once per frame
protected virtual void Update()
{
if (m_Status == EventWashingActionStatus.Preparing)
{
m_PrepareCumulativeTime += Time.deltaTime;
if (m_PrepareCumulativeTime >= m_PreparationTime)
{
if (m_ReadyAction != null)
{
m_ReadyAction.Invoke(this);
}
m_PrepareCumulativeTime = 0f;
m_Status = EventWashingActionStatus.Executing;
StopPlayPrepareAnimation();
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a33d07ea5bd0aa94582860610152f412
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,309 @@
//
// Outline.cs
// QuickOutline
//
// Created by Chris Nolet on 3/30/18.
// Copyright © 2018 Chris Nolet. All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[DisallowMultipleComponent]
public class Outline : MonoBehaviour {
private static HashSet<Mesh> registeredMeshes = new HashSet<Mesh>();
public enum Mode {
OutlineAll,
OutlineVisible,
OutlineHidden,
OutlineAndSilhouette,
SilhouetteOnly
}
public Mode OutlineMode {
get { return outlineMode; }
set {
outlineMode = value;
needsUpdate = true;
}
}
public Color OutlineColor {
get { return outlineColor; }
set {
outlineColor = value;
needsUpdate = true;
}
}
public float OutlineWidth {
get { return outlineWidth; }
set {
outlineWidth = value;
needsUpdate = true;
}
}
[Serializable]
private class ListVector3 {
public List<Vector3> data;
}
[SerializeField]
private Mode outlineMode;
[SerializeField]
private Color outlineColor = Color.white;
[SerializeField, Range(0f, 10f)]
private float outlineWidth = 2f;
[Header("Optional")]
[SerializeField, Tooltip("Precompute enabled: Per-vertex calculations are performed in the editor and serialized with the object. "
+ "Precompute disabled: Per-vertex calculations are performed at runtime in Awake(). This may cause a pause for large meshes.")]
private bool precomputeOutline;
[SerializeField, HideInInspector]
private List<Mesh> bakeKeys = new List<Mesh>();
[SerializeField, HideInInspector]
private List<ListVector3> bakeValues = new List<ListVector3>();
private Renderer[] renderers;
private Material outlineMaskMaterial;
private Material outlineFillMaterial;
private bool needsUpdate;
void Awake() {
// Cache renderers
renderers = GetComponentsInChildren<Renderer>();
// Instantiate outline materials
outlineMaskMaterial = Instantiate(Resources.Load<Material>(@"Materials/OutlineMask"));
outlineFillMaterial = Instantiate(Resources.Load<Material>(@"Materials/OutlineFill"));
outlineMaskMaterial.name = "OutlineMask (Instance)";
outlineFillMaterial.name = "OutlineFill (Instance)";
// Retrieve or generate smooth normals
LoadSmoothNormals();
// Apply material properties immediately
needsUpdate = true;
}
void OnEnable() {
foreach (var renderer in renderers) {
// Append outline shaders
var materials = renderer.sharedMaterials.ToList();
materials.Add(outlineMaskMaterial);
materials.Add(outlineFillMaterial);
renderer.materials = materials.ToArray();
}
}
void OnValidate() {
// Update material properties
needsUpdate = true;
// Clear cache when baking is disabled or corrupted
if (!precomputeOutline && bakeKeys.Count != 0 || bakeKeys.Count != bakeValues.Count) {
bakeKeys.Clear();
bakeValues.Clear();
}
// Generate smooth normals when baking is enabled
if (precomputeOutline && bakeKeys.Count == 0) {
Bake();
}
}
void Update() {
if (needsUpdate) {
needsUpdate = false;
UpdateMaterialProperties();
}
}
void OnDisable() {
foreach (var renderer in renderers) {
// Remove outline shaders
var materials = renderer.sharedMaterials.ToList();
materials.Remove(outlineMaskMaterial);
materials.Remove(outlineFillMaterial);
renderer.materials = materials.ToArray();
}
}
void OnDestroy() {
// Destroy material instances
Destroy(outlineMaskMaterial);
Destroy(outlineFillMaterial);
}
void Bake() {
// Generate smooth normals for each mesh
var bakedMeshes = new HashSet<Mesh>();
foreach (var meshFilter in GetComponentsInChildren<MeshFilter>()) {
// Skip duplicates
if (!bakedMeshes.Add(meshFilter.sharedMesh)) {
continue;
}
// Serialize smooth normals
var smoothNormals = SmoothNormals(meshFilter.sharedMesh);
bakeKeys.Add(meshFilter.sharedMesh);
bakeValues.Add(new ListVector3() { data = smoothNormals });
}
}
void LoadSmoothNormals() {
// Retrieve or generate smooth normals
foreach (var meshFilter in GetComponentsInChildren<MeshFilter>()) {
// Skip if smooth normals have already been adopted
if (!registeredMeshes.Add(meshFilter.sharedMesh)) {
continue;
}
// Retrieve or generate smooth normals
var index = bakeKeys.IndexOf(meshFilter.sharedMesh);
var smoothNormals = (index >= 0) ? bakeValues[index].data : SmoothNormals(meshFilter.sharedMesh);
// Store smooth normals in UV3
meshFilter.sharedMesh.SetUVs(3, smoothNormals);
// Combine submeshes
var renderer = meshFilter.GetComponent<Renderer>();
if (renderer != null) {
CombineSubmeshes(meshFilter.sharedMesh, renderer.sharedMaterials);
}
}
// Clear UV3 on skinned mesh renderers
foreach (var skinnedMeshRenderer in GetComponentsInChildren<SkinnedMeshRenderer>()) {
// Skip if UV3 has already been reset
if (!registeredMeshes.Add(skinnedMeshRenderer.sharedMesh)) {
continue;
}
// Clear UV3
skinnedMeshRenderer.sharedMesh.uv4 = new Vector2[skinnedMeshRenderer.sharedMesh.vertexCount];
// Combine submeshes
CombineSubmeshes(skinnedMeshRenderer.sharedMesh, skinnedMeshRenderer.sharedMaterials);
}
}
List<Vector3> SmoothNormals(Mesh mesh) {
// Group vertices by location
var groups = mesh.vertices.Select((vertex, index) => new KeyValuePair<Vector3, int>(vertex, index)).GroupBy(pair => pair.Key);
// Copy normals to a new list
var smoothNormals = new List<Vector3>(mesh.normals);
// Average normals for grouped vertices
foreach (var group in groups) {
// Skip single vertices
if (group.Count() == 1) {
continue;
}
// Calculate the average normal
var smoothNormal = Vector3.zero;
foreach (var pair in group) {
smoothNormal += smoothNormals[pair.Value];
}
smoothNormal.Normalize();
// Assign smooth normal to each vertex
foreach (var pair in group) {
smoothNormals[pair.Value] = smoothNormal;
}
}
return smoothNormals;
}
void CombineSubmeshes(Mesh mesh, Material[] materials) {
// Skip meshes with a single submesh
if (mesh.subMeshCount == 1) {
return;
}
// Skip if submesh count exceeds material count
if (mesh.subMeshCount > materials.Length) {
return;
}
// Append combined submesh
mesh.subMeshCount++;
mesh.SetTriangles(mesh.triangles, mesh.subMeshCount - 1);
}
void UpdateMaterialProperties() {
// Apply properties according to mode
outlineFillMaterial.SetColor("_OutlineColor", outlineColor);
switch (outlineMode) {
case Mode.OutlineAll:
outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
break;
case Mode.OutlineVisible:
outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
break;
case Mode.OutlineHidden:
outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Greater);
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
break;
case Mode.OutlineAndSilhouette:
outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
break;
case Mode.SilhouetteOnly:
outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Greater);
outlineFillMaterial.SetFloat("_OutlineWidth", 0f);
break;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7227527bced7eb64a8daf3095fd332d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using cfg;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class ToolBubbleGun : ToolForResponsiveCleaner
{
#region
public override void InitTool()
{
base.InitTool();
m_Type = EventWashingTool.FoamSprayer;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26a5ca7c43397254f8a5cdd4566291b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class ToolCollection : MonoBehaviour
{
public List<OperatingToolsBase> Tools = new List<OperatingToolsBase>();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0af65a08f04dedc4ab200eaff1bbc959
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class ToolForFollowerAndNormalPosition : OperatingToolsBase
{
[Tooltip("工具距离操作点位置, 吸尘器/水枪等 本身到吸嘴距离")]
[SerializeField]
private float m_DistanceToMouth = 0.1f;
[Tooltip("工具操作点距离操作区距离, 吸尘器/水枪等 吸嘴离地距离")]
[SerializeField]
private float m_DistanceFromMouthToGround = 0.4f;
[Tooltip("作用距离/覆盖范围")]
[SerializeField]
private float m_RangeCoverage = 0.8f;
[Tooltip("工具移动速度")]
[SerializeField]
private float m_ToolSpeed = 10f;
[Tooltip("工具移动耗时调整,按比例计算,正值为增加,负值为减少")]
[SerializeField]
private float m_ToolConsumedTimeAdjustedRatio = 0f;
public float DistanceFromMouthToGround { get => m_DistanceFromMouthToGround; }
public float RangeCoverage { get => m_RangeCoverage; }
private Vector3 m_OperatingPoint = Vector3.zero;
public Vector3 OperatingPoint { get => m_OperatingPoint; }
public void Follow(Vector3 position, Vector3 normal)
{
Vector3 targetPosition = position + normal * (m_DistanceToMouth + m_DistanceFromMouthToGround);
float distance = Vector3.Distance(targetPosition, this.transform.position);
float time = distance / m_ToolSpeed;
time += time * m_ToolConsumedTimeAdjustedRatio;
m_OperatingPoint = position + normal * m_DistanceFromMouthToGround;
this.transform.DOKill();
this.transform.DOMove(targetPosition, time).SetEase(Ease.OutQuad);
this.transform.DORotateQuaternion(Quaternion.LookRotation(-normal), time).SetEase(Ease.Linear);
}
#region Transform变换相关
public override void MoveToExhibition()
{
// 停止播放操作动画
StopPlayOperationAnimation();
// 停止播放准备动画
StopPlayPrepareAnimation();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b990b7047f8703f4d92bfbaee7dc7143
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class ToolForResponsiveCleaner : ToolForFollowerAndNormalPosition
{
[Tooltip("喷涂动画")]
[SerializeField]
private SprayAnimation m_SprayAnimation = null;
#region
protected override void PlayOperationAnimation()
{
base.PlayOperationAnimation();
if (m_SprayAnimation != null ) { m_SprayAnimation.PlayEffect(); }
}
protected override void StopPlayOperationAnimation()
{
base.StopPlayOperationAnimation();
if (m_SprayAnimation != null) { m_SprayAnimation.StopEffect(); }
}
#endregion
#region
public override void InitTool()
{
base.InitTool();
m_SprayAnimation.StopEffect();
m_SprayAnimation.DisableEffect();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 36d513f4aabe5d742b1d06e036c77af4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,124 @@
using cfg;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using UnityEngine;
namespace game
{
public class ToolShovel : OperatingToolsBase
{
[Tooltip("动画")]
[SerializeField]
private Animation m_Animation = null;
[Tooltip("循环动画")]
[SerializeField]
private string m_LoopAnimation = null;
[Tooltip("最后一击动画")]
[SerializeField]
private string m_FinalBlowAnimation = null;
[Tooltip("循环动画声音节点")]
[SerializeField]
private GameObject m_LoopAnimationNode = null;
[Tooltip("最后一击动画声音节点")]
[SerializeField]
private GameObject m_FinalBlowAnimationNode = null;
#region
public override void Enter1stStage()
{
base.Enter1stStage();
if (m_Animation != null)
{
m_Animation.Play(m_LoopAnimation);
}
if (m_LoopAnimationNode != null && m_LoopAnimationNode.activeSelf == false)
{
m_LoopAnimationNode.SetActive(true);
}
}
public override void Exit1stStage()
{
base.Exit1stStage();
if (m_Animation != null)
{
m_Animation.Stop(m_LoopAnimation);
m_Animation.transform.localPosition = Vector3.zero;
m_Animation.transform.localEulerAngles = Vector3.zero;
}
if (m_LoopAnimationNode != null && m_LoopAnimationNode.activeSelf == true)
{
m_LoopAnimationNode.SetActive(false);
}
}
public override void Enter2ndStage()
{
base.Enter2ndStage();
if (m_Animation != null)
{
m_Animation.Play(m_FinalBlowAnimation);
}
if (m_FinalBlowAnimationNode != null && m_FinalBlowAnimationNode.activeSelf == false)
{
m_FinalBlowAnimationNode.SetActive(true);
}
}
public override void Exit2ndStage()
{
base.Exit2ndStage();
if (m_Animation != null)
{
m_Animation.transform.localPosition = Vector3.zero;
m_Animation.transform.localEulerAngles = Vector3.zero;
}
if (m_FinalBlowAnimationNode != null && m_FinalBlowAnimationNode.activeSelf == true)
{
m_FinalBlowAnimationNode.SetActive(false);
}
}
private void StopAllAnimation()
{
if (m_Animation != null)
{
m_Animation.Stop();
m_Animation.transform.localPosition = Vector3.zero;
m_Animation.transform.localEulerAngles = Vector3.zero;
}
if (m_LoopAnimationNode != null && m_LoopAnimationNode.activeSelf == true)
{
m_LoopAnimationNode.SetActive(false);
}
if (m_FinalBlowAnimationNode != null && m_FinalBlowAnimationNode.activeSelf == true)
{
m_FinalBlowAnimationNode.SetActive(false);
}
}
public override void StopExecuting()
{
base.StopExecuting();
StopAllAnimation();
}
#endregion
#region
public override void InitTool()
{
base.InitTool();
m_Type = EventWashingTool.Shovel;
m_PrepareCumulativeTime = 0f;
StopAllAnimation();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d49af091646d384796cea1ce36df9ed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
using cfg;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class ToolSpanner : OperatingToolsBase
{
[Tooltip("动画")]
[SerializeField]
private Animation m_Animation = null;
[Tooltip("循环动画")]
[SerializeField]
private string m_LoopAnimation = null;
[Tooltip("循环动画声音节点")]
[SerializeField]
private GameObject m_LoopAnimationNode = null;
#region
protected override void PlayOperationAnimation()
{
base.PlayOperationAnimation();
if (m_Animation != null)
{
m_Animation.Play(m_LoopAnimation);
m_IsAuthorizedAnimation = true;
}
if (m_LoopAnimationNode != null && m_LoopAnimationNode.activeSelf == false)
{
m_LoopAnimationNode.SetActive(true);
}
}
protected override void StopPlayOperationAnimation()
{
base.StopPlayOperationAnimation();
StopAllAnimation();
}
private void StopAllAnimation()
{
if (m_Animation != null)
{
m_Animation.Stop();
m_Animation.transform.localPosition = Vector3.zero;
m_Animation.transform.localEulerAngles = Vector3.zero;
}
if (m_LoopAnimationNode != null && m_LoopAnimationNode.activeSelf == true)
{
m_LoopAnimationNode.SetActive(false);
}
}
public override void StopExecuting()
{
base.StopExecuting();
StopAllAnimation();
}
#endregion
#region
public override void InitTool()
{
base.InitTool();
m_Type = EventWashingTool.Spanner;
m_PrepareCumulativeTime = 0f;
StopAllAnimation();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f07ef0072122b9242a239e3d9e35bf13
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using cfg;
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class ToolVacuumCleaner : ToolForFollowerAndNormalPosition
{
[Tooltip("循环特效")]
[SerializeField]
private ParticleSystem[] m_LoopEffects = null;
#region
private bool m_IsPlayingEffect = false;
public override void StartExecuting()
{
if (m_LoopEffects == null || m_IsPlayingEffect == true) return;
m_IsPlayingEffect = true;
int count = m_LoopEffects.Length;
for (int i = 0; i < count; i++)
{
m_LoopEffects[i].gameObject.SetActive(true);
m_LoopEffects[i].Play();
}
}
public override void StopExecuting()
{
if (m_LoopEffects == null) return;
m_IsPlayingEffect = false;
int count = m_LoopEffects.Length;
for (int i = 0; i < count; i++)
{
m_LoopEffects[i].Stop();
m_LoopEffects[i].gameObject.SetActive(false);
}
}
#endregion
#region
public override void InitTool()
{
base.InitTool();
m_Type = EventWashingTool.Cleaner;
m_IsPlayingEffect = false;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e9f93b21c65941e4ea6319d8ccbc287f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using cfg;
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class ToolWaterGun : ToolForResponsiveCleaner
{
#region
public override void InitTool()
{
base.InitTool();
m_Type = EventWashingTool.WaterSprayer;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 756bbf0cc789237458db69c086373380
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3dd689b0905ebd44aa4fbb1a3e8e268d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,133 @@
using cfg;
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class WashingGameAssembling : WashingGameRemove
{
#region
protected Transform m_OriginalTransform;
private LongPressStuffBase m_NewItem;
protected override void OperatedItemExecuteOverAction(LongPressStuffBase stuffBase)
{
// 道具飞回展示区
m_Tool.MoveToExhibition();
m_CurOperatedItem.StopAction();
m_OriginalTransform = m_CurOperatedItem.transform;
m_NewItem = m_CurOperatedItem;
m_CurOperatedItem.gameObject.SetActive(false);
m_CurOperatedItem = null;
m_Status = EventWashingActionStatus.Ending;
NewItemFallOff();
int count = m_OperatedItems.Count;
for (int i = 0; i < count; i++)
{
if (stuffBase == m_OperatedItems[i])
{
m_DataManager.WashingData.StepItems[i] = 1f;
break;
}
}
m_DataManager.SyncData();
}
private void NewItemFallOff()
{
m_NewItem.transform.position = m_NewItem.transform.position + new Vector3(0f, m_BouncingDistance, 0f);
m_NewItem.gameObject.SetActive(true);
m_NewItem.transform.GetComponent<Collider>().enabled = false;
((StuffAssembling)m_NewItem).RestoreMaterial();
((StuffAssembling)m_NewItem).StopBreathing();
var tmp = m_NewItem;
m_NewItem.transform.DOMoveY(m_NewItem.transform.position.y - m_BouncingDistance, m_BouncingTime).SetEase(Ease.OutQuad).OnComplete(() =>
{
tmp = null;
m_Status = EventWashingActionStatus.Ending;
if (OperatedItemProgress >= 0.999f)
{
if (m_DataManager != null)
{
m_DataManager.WashingData.Percent = 1f;
m_DataManager.WashingData.IsOver = true;
m_DataManager.SyncData();
}
FishingYachtAct.Publish<EventWashingConclusionData>(new EventWashingConclusionData());
}
});
}
#endregion
#region
protected override void SyncGameData()
{
if (m_DataManager == null) return;
EventWashingData washingData = m_DataManager.WashingData;
bool syncData = false;
int count = m_OperatedItems.Count;
if (washingData.StepItems.Count == 0 && washingData.Percent == 0f && washingData.IsOver == false)
{
for (int i = 0; i < count; i++)
{
washingData.StepItems.Add(0f);
}
syncData = true;
}
else
{
for (int i = 0; i < count; i++)
{
if (washingData.StepItems.Count == i)
{
washingData.StepItems.Add(0f);
m_OperatedItems[i].SetHaveExecutedTime(0f);
m_OperatedItems[i].gameObject.SetActive(true);
syncData = true;
}
else if (washingData.StepItems[i] >= 1f)
{
m_OperatedItems[i].SetHaveExecutedTime(m_OperatedItems[i].ConsumeTime);
//if (!washingData.IsOver)
//{
// m_OperatedItems[i].gameObject.SetActive(false);
//}
((StuffAssembling)m_OperatedItems[i]).RestoreMaterial();
((StuffAssembling)m_OperatedItems[i]).StopBreathing();
}
else
{
m_OperatedItems[i].SetHaveExecutedTime(washingData.StepItems[i] * m_OperatedItems[i].ConsumeTime);
m_OperatedItems[i].gameObject.SetActive(true);
}
}
}
if (syncData) m_DataManager.SyncData();
}
#endregion
#region
public override void InitGame(string name)
{
base.InitGame(name);
this.m_GameType = EventWashingOperation.Installing;
this.m_Status = EventWashingActionStatus.Invalid;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 12ccc6deaba02874fae1e1ae8d095368
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,449 @@
using asap.core;
using cfg;
using Cinemachine;
using GameCore;
using System;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
namespace game
{
public class WashingGameBase : MonoBehaviour
{
[Tooltip("游戏ID")]
public int m_GameID = 0;
[Tooltip("摄像机跟随路径")]
public CinemachinePath m_CameraPath;
[Tooltip("路径停歇点索引,循环执行。eg:5个点执行到最后一个位置会从移动到初始位置开始。")]
public List<int> m_RestIndexList = new List<int>();
[Tooltip("摄像机移动速度")]
public float m_CameraSpeed = 4f;
[Tooltip("磁性距离,距离目标点一定距离,即认为到达目标点。")]
public float m_MagneticDistance = 0.01f;
[Tooltip("摄像机聚焦的位置(Transform)。")]
[SerializeField] protected Transform m_CameraFocusedTransform;
#region
protected CameraFollowPathMoveController m_CameraMoveController;
/// <summary>
/// 停靠点数量
/// </summary>
/// <returns></returns>
protected int GetCameraPathRestCount()
{
if (m_CameraMoveController == null) return 0;
return m_CameraMoveController.RestCount;
}
/// <summary>
/// 摄像机跳转停靠点索引
/// </summary>
/// <param name="index"></param>
protected void JumpCameraToRestIndex(int index)
{
if (m_CameraMoveController == null) return;
m_CameraMoveController.JumpToRestIndex(index);
}
/// <summary>
/// 摄像机向前移动到下一个停靠点
/// </summary>
protected void ForwardCameraToNextRest()
{
if (m_CameraMoveController is null) return;
m_CameraMoveController.ForwardToNextRest();
}
/// <summary>
/// 摄像机向后移动到下一个停靠点
/// </summary>
protected void BackwardCameraToNextRest()
{
if (m_CameraMoveController is null) return;
m_CameraMoveController.BackwardToNextRest();
}
/// <summary>
/// 当前停靠点索引
/// </summary>
/// <returns></returns>
public int GetCameraCurrentMoveIndex()
{
if (m_CameraMoveController is null) return 0;
return m_CameraMoveController.MoveIndex;
}
/// <summary>
/// 向前跳到下一个停靠点
/// </summary>
protected void JumpCameraToNextRestForward()
{
if (m_CameraMoveController is null) return;
m_CameraMoveController.JumpToNextRestForward();
}
/// <summary>
/// 向后跳到下一个停靠点
/// </summary>
protected void JumpCameraToNextRestBackward()
{
if (m_CameraMoveController is null) return;
int index = m_CameraMoveController.JumpToNextRestBackward();
}
#endregion
#region &
// 游戏类型
protected EventWashingOperation m_GameType = EventWashingOperation.None;
public EventWashingOperation GameType { get => m_GameType; }
protected string m_GameName;
//private bool m_IsGamePausing = false;
protected CinemachineVirtualCamera m_VirtualCamera;
public int GameID { get => m_GameID; }
protected EventWashingDataManager m_DataManager;
/// <summary>
/// 设置数据
/// </summary>
/// <param name="virtualCamera"></param>
/// <param name="cameraFollowPathMoveController"></param>
/// <param name="tool"></param>
public virtual void ResetAndInitData(CinemachineVirtualCamera virtualCamera, CameraFollowPathMoveController cameraFollowPathMoveController, OperatingToolsBase tool)
{
if (virtualCamera != null)
{
m_VirtualCamera = virtualCamera;
if (m_CameraFocusedTransform != null)
{
m_VirtualCamera.LookAt = m_CameraFocusedTransform;
}
}
else
{
Debug.LogError("--- WashingGameBase ResetAndInitData 找不到虚拟相机virtualCamera");
}
if (cameraFollowPathMoveController != null && m_CameraPath != null && m_RestIndexList != null)
{
m_CameraMoveController = cameraFollowPathMoveController;
m_CameraMoveController.ResetAndInit(m_CameraPath, m_RestIndexList, m_MagneticDistance);
m_CameraMoveController.JumpToRestIndex(0);
m_CameraMoveController.enabled = true;
m_CameraMoveController.Speed = m_CameraSpeed;
}
else
{
Debug.LogError("--- WashingGameBase ResetAndInitData 找不到正确的路径配置PathMoveControlle、CameraPath 或者 RestIndexList");
}
if (tool != null)
{
m_Tool = tool;
m_Tool.gameObject.SetActive(true);
m_Tool.JumpToExhibition();
m_Tool.StopExecuting();
}
else
{
Debug.LogError("--- WashingGameBase ResetAndInitData 找不到工具包");
}
}
protected EventWashingActionStatus m_Status = EventWashingActionStatus.Invalid;
/// <summary>
/// 切换状态
/// </summary>
/// <param name="status"></param>
protected void ChangeStatus(EventWashingActionStatus status)
{
m_Status = status;
}
#endregion
#region
protected List<UpdateOperationSet> m_UpdateOperationSets = new List<UpdateOperationSet>();
private bool m_IsShowingTokenNotEnough = false;
private float m_ShowingTokenNotEnoughCD = 0.0f;
/// <summary>
/// 代币是否足够消费
/// </summary>
/// <param name="spend"></param>
/// <returns></returns>
protected bool IsTokenEnough(int spend)
{
if (m_DataManager == null) return false;
bool isEnough = m_DataManager.IsEnough(spend);
if (isEnough == false && m_IsShowingTokenNotEnough == false)
{
ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_89"));
m_IsShowingTokenNotEnough = true;
}
m_ShowingTokenNotEnoughCD = 0.3f;
return isEnough;
}
protected bool ConsumeTokens(int count)
{
if (m_DataManager == null) return false;
bool isEnough = m_DataManager.ConsumeTokens(count);
if (isEnough == false)
{
if (m_IsShowingTokenNotEnough == false)
{
ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_89"));
m_IsShowingTokenNotEnough = true;
}
m_ShowingTokenNotEnoughCD = 0.3f;
m_DataManager.SetEnergy(0f, 0f);
SetEnergyShortage();
PauseGame();
}
else
{
ResumeGame();
SetEnergyEnough();
float step = 1f / m_DataManager.WashingData.StepEnergyConsume;
m_DataManager.SetEnergy(1f, step);
UpdateOperationSet updateOperationSet = GetUpdateOperationSet();
if (updateOperationSet != null) m_UpdateOperationSets.Add(updateOperationSet);
}
return isEnough;
}
protected virtual void UpdateTokenConsume()
{
if (m_DataManager == null || m_DataManager.WashingData == null) return;
if (m_DataManager.WashingData.Energy <= 0f || m_DataManager.WashingData.EnergyConsumptionSpeed <= 0f) return;
ResumeGame();
SetEnergyEnough();
UpdateOperationSet updateOperationSet = GetUpdateOperationSet();
if (updateOperationSet != null) m_UpdateOperationSets.Add(updateOperationSet);
}
protected virtual UpdateOperationSet GetUpdateOperationSet()
{
if (m_DataManager == null) return null;
UpdateOperationSet updateOperationSet = new UpdateOperationSet();
updateOperationSet.Update = m_DataManager.UpdateToken;
updateOperationSet.IsUpdateOver = m_DataManager.IsUpdateTokenOver;
updateOperationSet.Callback = ConsumeTokens;
return updateOperationSet;
}
protected virtual void SetEnergyShortage()
{
}
protected virtual void SetEnergyEnough()
{
}
protected bool HaveEnergy()
{
if (m_DataManager != null && m_DataManager.WashingData != null) return m_DataManager.WashingData.Energy > 0f;
return false;
}
#endregion
#region
// 操作工具
protected OperatingToolsBase m_Tool;
public OperatingToolsBase ToolsBase { get => m_Tool; }
/// <summary>
/// 工具跳转到展示区
/// </summary>
public void JumpToolToExhibition()
{
if (m_Tool == null) return;
m_Tool.JumpToExhibition();
}
/// <summary>
/// 工具移动到操作区 Transform
/// </summary>
/// <param name="transform"></param>
public void MoveToolToTransform(Transform transform)
{
if (m_Tool is null) return;
m_Tool.MoveToTransform(transform);
}
/// <summary>
/// 工具移动到展示区
/// </summary>
public void MoveToolToExhibition()
{
if (m_Tool is null) return;
m_Tool.MoveToExhibition();
}
#endregion
#region
protected bool m_IsGuiding = false;
#endregion
#region
protected virtual void OnEnable()
{
}
protected virtual void OnDisable()
{
disposables.Dispose();
}
protected virtual void OnDestroy()
{
disposables.Dispose();
disposables = null;
}
protected virtual void Update()
{
if (m_ShowingTokenNotEnoughCD > 0f)
{
m_ShowingTokenNotEnoughCD -= Time.deltaTime;
if (m_ShowingTokenNotEnoughCD <= 0f)
{
m_ShowingTokenNotEnoughCD = 0f;
m_IsShowingTokenNotEnough = false;
}
}
}
protected virtual void LateUpdate()
{
int count = m_UpdateOperationSets.Count;
for (int i = count - 1; i >= 0; i--)
{
var updateOperationSet = m_UpdateOperationSets[i];
if (updateOperationSet != null)
{
updateOperationSet.Update(Time.deltaTime);
if (updateOperationSet.IsUpdateOver())
{
if (!IsGameOver())
updateOperationSet.Callback(1);
m_UpdateOperationSets.Remove(updateOperationSet);
}
}
}
}
public virtual void InitGame(string name)
{
this.m_GameName = name;
this.m_GameType = EventWashingOperation.None;
this.m_Status = EventWashingActionStatus.Invalid;
}
public virtual void EnterGame()
{
}
protected virtual void AfterEnterGame()
{
if (m_DataManager != null)
{
if (m_DataManager.IsEnough(1)) SetEnergyEnough();
else SetEnergyShortage();
}
}
public virtual void SaveContext()
{
}
public virtual void LoadContext()
{
}
public virtual void SyncData()
{
if (m_DataManager != null)
{
m_DataManager.SyncData();
}
}
protected virtual void PauseGame()
{
//m_IsGamePausing = true;
}
protected virtual void ResumeGame()
{
//m_IsGamePausing = false;
}
public virtual void Fresh(EventWashingDataManager dataManager)
{
m_DataManager = dataManager;
SyncData();
UpdateTokenConsume();
if (m_DataManager != null && dataManager.WashingData != null) dataManager.WashingData.ClearLocalDataExceptGroup(m_GameName);
}
public virtual void GameOver()
{
SyncData();
if (m_CameraMoveController != null)
{
m_CameraMoveController.enabled = false;
}
if (m_Tool != null)
{
m_Tool.MoveToExhibition();
m_Tool.StopExecuting();
}
m_UpdateOperationSets.Clear();
}
public bool IsGameOver()
{
if (m_DataManager == null || m_DataManager.WashingData == null) return true;
bool isOver = m_DataManager.IsGameOver();
if (isOver) GameOver();
return isOver;
}
#endregion
#region
protected CompositeDisposable disposables = new CompositeDisposable();
public void Subscribe<T>(Action<T> eventAction, string eventId = null)
{
IObservable<T> observable = FishingYachtAct.GetEvent<T>(eventId);
if (observable != null)
{
observable.Subscribe<T>(eventAction).AddTo(disposables);
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f005cfb2d935a149ac9767b9eb75f64
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,66 @@
using cfg;
using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class WashingGameCleanBarnacles : WashingGameRemove
{
[Tooltip("摄像机移动路径停止位置索引")]
[SerializeField] private int m_PathStopIndex = 1;
#region
protected override void OperatedItemExecuteOverAction(LongPressStuffBase stuffBase)
{
base.OperatedItemExecuteOverAction(stuffBase);
// 道具飞回展示区
m_Tool.MoveToExhibition();
m_CurOperatedItem.StopAction();
m_CurOperatedItem.gameObject.SetActive(false);
}
public override void ResetAndInitData(CinemachineVirtualCamera virtualCamera, CameraFollowPathMoveController cameraFollowPathMoveController, OperatingToolsBase tool)
{
if (virtualCamera != null)
{
m_VirtualCamera = virtualCamera;
if (m_CameraFocusedTransform != null)
{
m_VirtualCamera.LookAt = m_CameraFocusedTransform;
}
}
if (cameraFollowPathMoveController != null && m_CameraPath != null && m_RestIndexList != null)
{
m_CameraMoveController = cameraFollowPathMoveController;
m_CameraMoveController.ResetAndInit(m_CameraPath, m_RestIndexList, m_MagneticDistance);
m_CameraMoveController.JumpToRestIndex(0);
m_CameraMoveController.enabled = true;
m_CameraMoveController.Speed = m_CameraSpeed;
m_CameraMoveController.GoToPositionIndex(m_PathStopIndex);
}
if (tool != null)
{
m_Tool = tool;
m_Tool.gameObject.SetActive(true);
m_Tool.JumpToExhibition();
m_Tool.StopExecuting();
}
}
#endregion
#region
public override void InitGame(string name)
{
base.InitGame(name);
this.m_GameType = EventWashingOperation.Barnacle;
this.m_Status = EventWashingActionStatus.Invalid;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 390ad44f0d1e484498b767c845f445c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using asap.core;
using cfg;
using GameCore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class WashingGameCleanFoam : WashingGamePainting
{
#region
protected override void StartConclusion(EventWashingConclusionData data)
{
if (m_PaintTexture != null)
{
//SetPaintTextureColor(Color.white);
SetPaintTextureColor(new Color(1f, 1f, 1f, 0f), true);
}
base.StartConclusion(data);
}
#endregion
#region
protected override void InitPanel()
{
base.InitPanel();
// 关闭笔刷填充进度
panel.ResetBrushChannelCounterFillAndInverse(true, true);
this.StartCoroutine(StartCountingFill());
}
private IEnumerator StartCountingFill()
{
int index = 0;
while (index < 10)
{
yield return null;
index++;
}
panel.StartCountingFill();
}
#endregion
#region
public override void InitGame(string name)
{
base.InitGame(name);
this.m_GameType = EventWashingOperation.Washing;
}
public override void Fresh(EventWashingDataManager dataManager)
{
SetPaintTextureColor(Color.white);
ChangePaintSphereBlendModeToSubtractiveSoft();
m_PainterColor = new Color(1f, 1f, 1f, 0f);
base.Fresh(dataManager);
if (m_PaintTexture != null) m_PaintTexture.gameObject.SetActive(true);
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0fc31cf4bce3d7e4bb374a65918c1433
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,613 @@
using asap.core;
using GameCore;
using PaintCore;
using PaintIn3D;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Mathematics;
using asap.core.common;
using CW.Common;
using UniRx;
namespace game
{
public class WashingGamePainting : WashingGameBase
{
[Tooltip("绘制用笔刷,主要用于喷洗泡沫等")]
public CwPaintSphere m_PaintSphere;
[Tooltip("绘制用纹理,主要用于喷洗泡沫等")]
public CwPaintableMeshTexture m_PaintTexture;
[Tooltip("玩家停止喷涂/清理后,持续播放动画时间")]
[SerializeField] private float m_ToolPlayingEffectTimeAfterStoppedPainting = 0.1f;
[Tooltip("飞溅动画预制体")]
[SerializeField]
private SplashAnimation m_SplashPrefab = null;
[Tooltip("飞溅特效延迟播放时间")]
[SerializeField]
private float m_SplashDelayTime = 0.2f;
[Tooltip("飞溅特特效显示时间")]
[SerializeField]
private float m_SplashDisplayTime = 0.1f;
[Tooltip("喷涂省略的比例范围0.0 - 1.0")]
[SerializeField] private float m_OmitPercentage = 0.1f;
IObjectPoolService m_ObjectPoolService;
#region
private float m_Timer = 0f;
#endregion
#region
private IObjectPool m_ObjectPool = null;
private IEnumerator CreateSplashClone(EventWashingCleanerFollowPositionData data)
{
yield return new WaitForSeconds(m_SplashDelayTime);
SplashAnimation clone = GetObjectPoolService().SpawnObject<SplashAnimation>();
clone.transform.position = data.position;
clone.transform.up = data.normal;
clone.SetTimer(m_SplashDisplayTime);
}
private IObjectPoolService GetObjectPoolService()
{
if (m_ObjectPoolService != null) return m_ObjectPoolService;
m_ObjectPoolService = GContext.container.Resolve<IObjectPoolService>();
m_ObjectPoolService.CreatePool<SplashAnimation>(m_SplashPrefab, 8, 32);
return m_ObjectPoolService;
}
private void DestroyObjectPool()
{
if (m_ObjectPoolService == null) return;
m_ObjectPoolService.DestroyPool<SplashAnimation>();
}
#endregion
#region
protected EventWashingPanel panel;
protected virtual void InitPanel()
{
panel.ResetBrushChannelCounterData();
panel.SetDataManager(m_DataManager);
if (m_DataManager.WashingData.IsAllGameOver == true)
{
panel.ShowForAllGameOver();
// 设置关闭按钮
panel.SetBtnCloseClickListener(OnBtnCloseClickListener);
return;
}
panel.StopCountingFill();
panel.ShowForPainting();
// 设置预览按钮
panel.SetBtnPreviewClickListener(null);
// 设置关闭按钮
panel.SetBtnCloseClickListener(OnBtnCloseClickListener);
// 设置左右箭头
panel.SetBtnArrayClickListener(OnBtnLeftClick, OnBtnRightClick);
m_IsGuiding = panel.InitGuidance();
if (m_IsGuiding == true)
{
StopInputOperation();
}
else
{
ResumeInputOperation();
}
}
private void OnBtnLeftClick()
{
// 向左移动机位
FishingYachtAct.Publish<EventWashingCameraMoveData>(new EventWashingCameraMoveData(EventWashingCameraMoveDirection.Backward));
}
private void OnBtnRightClick()
{
// 向右移动机位
FishingYachtAct.Publish<EventWashingCameraMoveData>(new EventWashingCameraMoveData(EventWashingCameraMoveDirection.Forward));
}
private void OnBtnCloseClickListener()
{
//SaveRenderTexture(m_PaintTexture.Current, Application.dataPath + "/../SavedScreen.png");
//return;
// 关闭当前Act
GContext.Publish(new UnloadActToNextAct());
}
private float m_PowerConsumptionTime = 0.4f;
private float m_PowerConsumptionCD = 0f;
private void HideElectricityConsumption()
{
if (m_PowerConsumptionCD > 0f) return;
panel.SetElectricityConsumptionVisible(false);
}
private void ShowElectricityConsumption()
{
m_PowerConsumptionCD = m_PowerConsumptionTime;
panel.SetElectricityConsumptionVisible(true);
}
#endregion
#region
protected void InitShipMaterial()
{
//if (m_ShipMaterials == null || m_ShipRenderer == null) return;
//m_ShipRenderer.sharedMaterials = m_ShipMaterials;
}
#endregion
#region
private bool m_IsDetectedAsInOperation = false;
#endregion
#region Paint in 3D
private void SaveRenderTexture(RenderTexture renderTexture, string file)
{
RenderTexture.active = renderTexture;
Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false, false);
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
texture.Apply();
byte[] bytes = texture.EncodeToPNG();
UnityEngine.Object.Destroy(texture);
System.IO.File.WriteAllBytes(file, bytes);
Debug.Log("write to File over");
//UnityEditor.AssetDatabase.Refresh(); //自动刷新资源
}
/// <summary>
/// 设置CwPaintSphere混合模式为AdditiveSoft
/// </summary>
public void ChangePaintSphereBlendModeToAdditiveSoft()
{
if (m_PaintSphere == null) return;
m_PaintSphere.enabled = true;
m_PaintSphere.gameObject.SetActive(true);
m_PaintSphere.BlendMode = CwBlendMode.AdditiveSoft(Vector4.one);
}
/// <summary>
/// 设置CwPaintSphere混合模式为SubtractiveSoft
/// </summary>
public void ChangePaintSphereBlendModeToSubtractiveSoft()
{
if (m_PaintSphere == null) return;
m_PaintSphere.enabled = true;
m_PaintSphere.gameObject.SetActive(true);
m_PaintSphere.BlendMode = CwBlendMode.SubtractiveSoft(Vector4.one);
}
/// <summary>
/// 清空绘制用纹理
/// </summary>
public void ClearPaintTexture()
{
if (m_PaintTexture == null) return;
m_PaintTexture.Clear();
}
public void SetPaintTextureColor(Color color, bool isReplace = false)
{
if (m_PaintTexture == null) return;
m_PaintTexture.Color = color;
if (isReplace == true) m_PaintTexture.Replace();
BHitScreenBase.SetTargetTransform(m_PaintTexture.transform);
}
private void StopPainting(bool isInOperation = true)
{
if (m_PaintSphere == null) return;
//m_PaintSphere.gameObject.SetActive(false);
if (m_Tool != null)
{
m_Tool.NotAuthorizedAnimation();
}
BHitScreen bHitScreen = m_PaintSphere.transform.transform.GetComponent<BHitScreen>();
if (bHitScreen != null)
{
bHitScreen.NotAuthorizedDrawing();
}
m_IsDetectedAsInOperation = isInOperation;
}
private void ResumePainting()
{
if (m_PaintSphere == null) return;
if (m_Tool != null)
{
m_Tool.AuthorizedAnimation();
}
BHitScreen bHitScreen = m_PaintSphere.transform.GetComponent<BHitScreen>();
if (bHitScreen != null && HaveEnergy())
{
bHitScreen.AuthorizedDrawing();
}
m_IsDetectedAsInOperation = false;
}
private void StopInputOperation()
{
var pointers = m_PaintSphere.transform.GetComponents<CwPointer>();
if (pointers != null)
{
foreach (var pointer in pointers)
{
pointer.enabled = false;
}
}
}
private void ResumeInputOperation()
{
var pointers = m_PaintSphere.transform.GetComponents<CwPointer>();
if (pointers != null)
{
foreach (var pointer in pointers)
{
pointer.enabled = true;
}
}
}
#endregion
#region
private void InitEvent()
{
this.Subscribe<EventWashingGestureFollowPositionData>(SetGestureFollowPosition);
this.Subscribe<EventWashingConclusionData>(StartConclusion);
this.Subscribe<EventWashingStepOverData>(StepOver);
this.Subscribe<EventWashingCleanerFollowPositionData>(SetCleanerFollowPosition);
this.Subscribe<EventWashingCameraMoveData>(EventCameraForwardListener); // 摄像机移动处理
this.Subscribe<EventWashingCameraStopData>(EventWashingCameraStopListener);
this.Subscribe<EventWashingMonitoringFoamProgressData>(EventMonitoringFoamProgressListener);
this.Subscribe<EventWashingAllGameOverData>(AllGameOver);
this.Subscribe<EventWashingTokenUpdateData>(UpdateBatteryInfo);
GContext.OnEvent<AddIndexEvent>().Subscribe(GuideListener).AddTo(this.disposables);
}
private void GuideListener(AddIndexEvent addIndexEvent)
{
if (addIndexEvent.CompleteGuide == true && panel != null)
{
panel.CompleteGuidance();
m_IsGuiding = false;
ResumeInputOperation();
}
}
private bool m_IsUpdateBatteryInfo = true;
private void UpdateBatteryInfo(EventWashingTokenUpdateData data)
{
if (panel != null && m_IsUpdateBatteryInfo == true)
{
panel.SetBatteryInfo();
}
}
private void AllGameOver(EventWashingAllGameOverData data)
{
if (panel != null)
{
panel.ShowForAllGameOver();
}
}
private void EventMonitoringFoamProgressListener(EventWashingMonitoringFoamProgressData data)
{
if (m_DataManager != null)
{
m_DataManager.WashingData.Percent = data.progress;
m_DataManager.WashingData.OmitPercent = m_OmitPercentage;
}
}
private void EventCameraForwardListener(EventWashingCameraMoveData data)
{
if (m_CameraMoveController != null)
{
if (data.direction == EventWashingCameraMoveDirection.Forward)
{
m_CameraMoveController.ForwardToNextRest();
}
else if (data.direction == EventWashingCameraMoveDirection.Backward)
{
m_CameraMoveController.BackwardToNextRest();
}
StopPainting();
}
}
private void EventWashingCameraStopListener(EventWashingCameraStopData data)
{
ResumePainting();
}
private void SetGestureFollowPosition(EventWashingGestureFollowPositionData data)
{
if (data.isFollowing)
{
ShowElectricityConsumption();
//Vector3 worldPosition = Vector3.zero;
RectTransformUtility.ScreenPointToWorldPointInRectangle(
panel.gestureFollow.transform.GetComponent<RectTransform>(),
data.position,
UIManager.Instance.UICanvas.worldCamera,
out Vector3 worldPosition);
panel.SetGestureFollowPosition(worldPosition);
}
else
{
HideElectricityConsumption();
}
}
private void SetCleanerFollowPosition(EventWashingCleanerFollowPositionData data)
{
if (!IsGameOver() && (HaveEnergy() || ConsumeTokens(1)))
{
ResumePainting();
}
else
{
// 停止游戏
StopPainting(false);
}
if (m_Tool != null)
{
((ToolForFollowerAndNormalPosition)m_Tool).Follow(data.position, data.normal);
m_Tool.StartExecuting();
m_Timer = m_ToolPlayingEffectTimeAfterStoppedPainting;
if (m_SplashPrefab != null && m_Tool.IsAuthorizedAnimation)
{
StartCoroutine(CreateSplashClone(data));
}
}
}
protected virtual void StartConclusion(EventWashingConclusionData data)
{
if (m_DataManager != null)
{
m_DataManager.WashingData.IsOver = true;
m_DataManager.SyncData();
}
panel.StopCountingFill();
panel.StartConclusion();
}
private void StepOver(EventWashingStepOverData data)
{
m_IsUpdateBatteryInfo = false;
GameOver();
FishingYachtAct.Publish<EventWashingGameOverData>(new EventWashingGameOverData());
}
#endregion
#region
protected void UpdateToken(float deltaTime)
{
if (m_DataManager == null || m_DataManager.WashingData == null) return;
float step = 1f / m_DataManager.WashingData.StepEnergyConsume;
float tmpProgress = 1f - m_DataManager.WashingData.OmitPercent;
float realProgress = m_DataManager.WashingData.Percent / tmpProgress;
if (realProgress > 1) realProgress = 1;
float nextEnergy = 1f - math.frac(realProgress / step);
if (m_DataManager.WashingData.Energy < nextEnergy) m_DataManager.WashingData.Energy = 0f;
if (m_DataManager.WashingData.Energy > 0) m_DataManager.WashingData.Energy = nextEnergy;
if (m_DataManager.WashingData.Energy < 0) m_DataManager.WashingData.Energy = 0;
}
protected bool IsUpdateTokenOver()
{
if (m_DataManager == null || m_DataManager.WashingData == null) return true;
float step = 1f / m_DataManager.WashingData.StepEnergyConsume;
float tmpProgress = 1f - m_DataManager.WashingData.OmitPercent;
float realProgress = m_DataManager.WashingData.Percent / tmpProgress;
if (realProgress > 1) realProgress = 1;
int belongStep = (int)math.floor(realProgress / step) + 1;
if (belongStep > m_DataManager.WashingData.StepEnergyConsume) m_DataManager.WashingData.IsOver = true;
if (belongStep > m_DataManager.WashingData.ConsumedToken) return true;
return false;
}
protected override UpdateOperationSet GetUpdateOperationSet()
{
if (m_DataManager == null) return null;
UpdateOperationSet updateOperationSet = new UpdateOperationSet();
updateOperationSet.Update = UpdateToken;
updateOperationSet.IsUpdateOver = IsUpdateTokenOver;
updateOperationSet.Callback = ConsumeTokens;
return updateOperationSet;
}
#endregion
#region
protected Color m_PainterColor = Color.white;
private void SyncGameData()
{
if (m_DataManager == null || m_DataManager.WashingData == null) return;
if (m_PaintTexture == null) return;
if (m_PaintSphere == null) return;
if (m_PaintTexture.SaveLoad == PaintCore.CwPaintableTexture.SaveLoadType.Automatic && string.IsNullOrEmpty(m_PaintTexture.SaveName) == false)
{
m_DataManager.WashingData.AddLocalDataKey(m_GameName, m_PaintTexture.SaveName);
if (m_DataManager.WashingData.Percent <= 0) return;
bool isExists = CwCommon.SaveExists(m_PaintTexture.SaveName);
if (isExists == false)
{
int total = (int)(m_PaintTexture.Width * m_PaintTexture.Height * m_DataManager.WashingData.Percent);
int index = 0;
Texture2D texture = new Texture2D(m_PaintTexture.Width, m_PaintTexture.Height, TextureFormat.ARGB32, false, false);
for (int i = 0; i < texture.width; i++)
{
for (int j = 0; j < texture.height; j++)
{
if (index < total) texture.SetPixel(i, j, m_PainterColor);
else texture.SetPixel(i, j, m_PaintTexture.Color);
++index;
}
}
texture.Apply();
var data = texture.EncodeToPNG();
CwHelper.Destroy(texture);
CwCommon.SaveBytes(m_PaintTexture.SaveName, data);
}
}
}
protected override void SetEnergyEnough()
{
base.SetEnergyEnough();
if (panel != null) panel.SetEnergyEnough();
}
protected override void SetEnergyShortage()
{
base.SetEnergyShortage();
if (panel != null) panel.SetEnergyShortage();
}
#endregion
#region
public async override void EnterGame()
{
base.EnterGame();
m_IsUpdateBatteryInfo = true;
BrushChannelCounterFill.OmitPercentage = this.m_OmitPercentage;
StopPainting(false);
// 打开页面(UI)
GameObject pannelObj = await UIManager.Instance.ShowUI(UITypes.EventWashingPanel);
if (pannelObj == null) return;
panel = pannelObj.transform.GetComponent<EventWashingPanel>();
InitPanel();
InitEvent();
AfterEnterGame();
}
protected override void ResumeGame()
{
base.ResumeGame();
ResumePainting();
}
protected override void PauseGame()
{
base.PauseGame();
StopPainting(false);
}
public override void Fresh(EventWashingDataManager dataManager)
{
base.Fresh(dataManager);
m_IsGuiding = true;
StopInputOperation();
if (dataManager == null || dataManager.WashingData == null) return;
//if (m_PaintTexture != null) m_PaintTexture.DefaultFillRatio = dataManager.WashingData.Percent;
}
public override void SyncData()
{
SyncGameData();
base.SyncData();
}
protected override void OnEnable()
{
base.OnEnable();
GetObjectPoolService();
}
protected override void OnDisable()
{
base.OnDisable();
DestroyObjectPool();
}
protected override void Update()
{
base.Update();
m_Timer -= Time.deltaTime;
if (m_Timer <= 0)
{
m_Timer = 0f;
if (m_Tool != null) m_Tool.StopExecuting();
}
if (m_IsDetectedAsInOperation == true)
{
if (panel != null)
{
panel.ContinuousOperation();
}
}
m_PowerConsumptionCD -= Time.deltaTime;
if (m_PowerConsumptionCD <= 0)
{
m_PowerConsumptionCD = 0;
}
}
public override void GameOver()
{
base.GameOver();
if (panel != null) panel.StopCountingFill();
StopPainting();
// 关闭笔刷填充进度
if (panel != null)
{
panel.ResetBrushChannelCounterFillAndInverse(true, false);
}
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5e1f854c126aa3a4db818441d257c166
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,565 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using asap.core;
using GameCore;
using cfg;
using UniRx;
namespace game
{
public class WashingGameRemove : WashingGameBase
{
[Tooltip("弹跳距离。如:清理藤壶游戏中,清理藤壶后,藤壶向上方弹跳的距离,然后消失。安装座椅游戏中,新座椅从上方弹跳距离移动到椅子的位置。")]
public float m_BouncingDistance = 0.2f;
[Tooltip("弹跳时间。")]
public float m_BouncingTime = 0.1f;
[Tooltip("被操作的物品。如:清理藤壶游戏中的藤壶等。")]
public List<LongPressStuffBase> m_OperatedItems = new List<LongPressStuffBase>();
[Tooltip("操作区。如:清理藤壶游戏,铲子铲藤壶时,需要移动到的位置。")]
public List<Transform> m_OperationAreas = new List<Transform>();
#region
private EventWashingPanel panel;
private void InitPanel()
{
panel.SetDataManager(m_DataManager);
if (m_DataManager.WashingData.IsAllGameOver == true)
{
panel.ShowForAllGameOver();
// 设置关闭按钮
panel.SetBtnCloseClickListener(OnBtnCloseClickListener);
return;
}
panel.ShowForRemove();
// 设置预览按钮
panel.SetBtnPreviewClickListener(null);
// 设置关闭按钮
panel.SetBtnCloseClickListener(OnBtnCloseClickListener);
// 关闭笔刷填充进度
panel.ResetBrushChannelCounterFillAndInverse(false, false);
m_IsGuiding = panel.InitGuidance();
}
private void HideElectricityConsumption()
{
if (panel == null) return;
panel.SetElectricityConsumptionVisible(false);
}
private void ShowElectricityConsumption()
{
if (panel == null) return;
panel.SetElectricityConsumptionVisible(true);
}
private void OnBtnCloseClickListener()
{
// 关闭当前Act
GContext.Publish(new UnloadActToNextAct());
}
private void UpdatePanelProgress()
{
if (panel != null)
{
float progress = OperatedItemProgress;
if (progress == 0f)
{
panel.UpdateSingleProgress(progress);
return;
}
if (m_DataManager != null)
{
m_DataManager.WashingData.Percent = progress;
}
panel.UpdateSingleProgress(progress);
}
}
private void SetGestureFollowPosition(Vector2 position)
{
if (panel == null) return;
ShowElectricityConsumption();
//Vector3 worldPosition = Vector3.zero;
RectTransformUtility.ScreenPointToWorldPointInRectangle(
panel.gestureFollow.transform.GetComponent<RectTransform>(),
position,
UIManager.Instance.UICanvas.worldCamera,
out Vector3 worldPosition);
panel.SetGestureFollowPosition(worldPosition);
}
#endregion
#region
public List<LongPressStuffBase> OperatedItems
{
get { return m_OperatedItems; }
}
public List<Transform> OperationAreas
{
get { return m_OperationAreas; }
}
protected virtual void SyncGameData()
{
if (m_DataManager == null) return;
EventWashingData washingData = m_DataManager.WashingData;
bool syncData = false;
int count = m_OperatedItems.Count;
if (washingData.StepItems.Count == 0 && washingData.Percent == 0f && washingData.IsOver == false)
{
for (int i = 0; i < count; i++)
{
washingData.StepItems.Add(0f);
}
syncData = true;
}
else
{
for (int i = 0;i < count; i++)
{
if (washingData.StepItems.Count == i)
{
washingData.StepItems.Add(0f);
m_OperatedItems[i].SetHaveExecutedTime(0f);
m_OperatedItems[i].gameObject.SetActive(true);
syncData = true;
}
else if (washingData.StepItems[i] >= 1f)
{
m_OperatedItems[i].SetHaveExecutedTime(m_OperatedItems[i].ConsumeTime);
//if (!washingData.IsOver)
//{
// m_OperatedItems[i].gameObject.SetActive(false);
//}
m_OperatedItems[i].gameObject.SetActive(false);
}
else
{
m_OperatedItems[i].SetHaveExecutedTime(washingData.StepItems[i] * m_OperatedItems[i].ConsumeTime);
m_OperatedItems[i].gameObject.SetActive(true);
}
}
}
if (syncData) m_DataManager.SyncData();
}
protected override void SetEnergyEnough()
{
base.SetEnergyEnough();
if (panel != null) panel.SetEnergyEnough();
}
protected override void SetEnergyShortage()
{
base.SetEnergyShortage();
if (panel != null) panel.SetEnergyShortage();
}
protected void CheckIsOver()
{
if (OperatedItemProgress >= 0.999f)
{
if (m_DataManager != null)
{
m_DataManager.WashingData.Percent = 1f;
m_DataManager.WashingData.IsOver = true;
m_DataManager.SyncData();
}
FishingYachtAct.Publish<EventWashingConclusionData>(new EventWashingConclusionData());
}
}
#endregion
#region
/// <summary>
/// 工具准备工作结束回调
/// </summary>
/// <param name="operatingToolsBase"></param>
protected void OperatingToolsReadyAction(OperatingToolsBase operatingToolsBase)
{
if (m_Tool == null || m_CurOperatedItem == null) return;
if (operatingToolsBase.Status == EventWashingActionStatus.Preparing)
{
if (!IsGameOver() && (HaveEnergy() || ConsumeTokens(1)))
{
m_Tool.StartExecuting();
m_CurOperatedItem.StartAction(OperatedItemExecuteOverAction);
m_Status = EventWashingActionStatus.Executing;
}
}
}
/// <summary>
/// 杂物操作完成回调
/// </summary>
/// <param name="stuffBase"></param>
protected virtual void OperatedItemExecuteOverAction(LongPressStuffBase stuffBase)
{
// 道具飞回展示区
m_Tool.MoveToExhibition();
m_CurOperatedItem.StopAction();
int count = m_OperatedItems.Count;
for (int i = 0; i < count; i++)
{
if (stuffBase == m_OperatedItems[i])
{
m_DataManager.WashingData.StepItems[i] = 1f;
break;
}
}
m_DataManager.SyncData();
var tmp = m_CurOperatedItem;
m_CurOperatedItem.transform.DOMoveY(m_CurOperatedItem.transform.position.y + m_BouncingDistance, m_BouncingTime).SetEase(Ease.OutQuad).OnComplete(() =>
{
tmp.gameObject.SetActive(false);
tmp = null;
m_Status = EventWashingActionStatus.Ending;
if (OperatedItemProgress >= 0.999f)
{
if (m_DataManager != null)
{
m_DataManager.WashingData.Percent = 1f;
m_DataManager.WashingData.IsOver = true;
m_DataManager.SyncData();
}
FishingYachtAct.Publish<EventWashingConclusionData>(new EventWashingConclusionData());
}
});
}
protected void ChangeState2InvalidFromExecuting()
{
// 停止消耗电量
// 工具停止播放操作动画
// 道具飞回展示区
m_Tool.StopExecuting();
m_Tool.MoveToExhibition();
if (m_CurOperatedItem != null)
m_CurOperatedItem.StopAction();
m_Status = EventWashingActionStatus.Invalid;
}
protected void ChangeState2InvalidFromPreparing()
{
// 工具停止播放准备动画
// 道具飞回展示区
m_Tool.StopExecuting();
m_Tool.MoveToExhibition();
if (m_CurOperatedItem != null)
m_CurOperatedItem.StopAction();
m_Status = EventWashingActionStatus.Invalid;
}
protected void ChangeState2Invalid()
{
if (m_Tool != null && m_Tool.Status != EventWashingActionStatus.Invalid)
{
m_Tool.StopExecuting();
m_Tool.MoveToExhibition();
}
if (m_CurOperatedItem != null)
m_CurOperatedItem.StopAction();
m_Status = EventWashingActionStatus.Invalid;
}
#endregion
#region
protected LongPressStuffBase m_CurOperatedItem = null;
/// <summary>
/// 设置被操作物品已消耗时间
/// </summary>
/// <param name="time"></param>
public void SetOperatedItemHaveExecutedTime(int index, float time)
{
int count = m_OperatedItems.Count;
if (index < 0 || index >= count) return;
for (int i = 0; i < index; i++)
{
m_OperatedItems[i].SetOver();
}
m_OperatedItems[index].SetHaveExecutedTime(time);
for (int i = 0; i < count; i++)
{
m_OperatedItems[i].SetHaveExecutedTime(0f);
}
}
/// <summary>
/// 当前被操作物品进度
/// </summary>
public float OperatedItemProgress
{
get
{
float total = 0f;
float cumulativeTime = 0f;
int count = m_OperatedItems.Count;
EventWashingData washingData = null;
if (m_DataManager != null) washingData = m_DataManager.WashingData;
for (int i = 0; i < count; ++i)
{
var item = m_OperatedItems[i];
total += item.ConsumeTime;
cumulativeTime += item.CumulativeConsumeTime;
if (washingData != null) washingData.StepItems[i] = item.CumulativeConsumeTime / item.ConsumeTime;
}
return cumulativeTime / total;
}
}
protected void StopAllItemAction()
{
int count = m_OperatedItems.Count;
for (int i = 0; i < count; i++)
{
m_OperatedItems[i].StopAction();
}
}
#endregion
#region
private void InitEvent()
{
this.Subscribe<EventWashingConclusionData>(StartConclusion);
this.Subscribe<EventWashingStepOverData>(StepOver);
this.Subscribe<EventWashingAllGameOverData>(AllGameOver);
this.Subscribe<EventWashingTokenUpdateData>(UpdateBatteryInfo);
this.Subscribe<EventWashingToolEnter1stStageData>(ToolEnter1stStage);
this.Subscribe<EventWashingToolExit1stStageData>(ToolExit1stStage);
this.Subscribe<EventWashingToolEnter2ndStageData>(ToolEnter2ndStage);
this.Subscribe<EventWashingToolExit2ndStageData>(ToolExit2ndStage);
GContext.OnEvent<AddIndexEvent>().Subscribe(GuideListener).AddTo(this.disposables);
}
private void GuideListener(AddIndexEvent addIndexEvent)
{
if (addIndexEvent.CompleteGuide == true && panel != null)
{
panel.CompleteGuidance();
m_IsGuiding = false;
}
}
private void ToolEnter1stStage(EventWashingToolEnter1stStageData data)
{
if (m_Tool == null) return;
m_Tool.Enter1stStage();
}
private void ToolExit1stStage(EventWashingToolExit1stStageData data)
{
if (m_Tool == null) return;
m_Tool.Exit1stStage();
}
private void ToolEnter2ndStage(EventWashingToolEnter2ndStageData data)
{
if (m_Tool == null) return;
m_Tool.Enter2ndStage();
}
private void ToolExit2ndStage(EventWashingToolExit2ndStageData data)
{
if (m_Tool == null) return;
m_Tool.Exit2ndStage();
}
private bool m_IsUpdateBatteryInfo = true;
private void UpdateBatteryInfo(EventWashingTokenUpdateData data)
{
if (panel != null && m_IsUpdateBatteryInfo == true)
{
panel.SetBatteryInfo();
}
}
protected virtual void StartConclusion(EventWashingConclusionData data)
{
panel.StartConclusion();
}
private void StepOver(EventWashingStepOverData data)
{
m_IsUpdateBatteryInfo = false;
GameOver();
FishingYachtAct.Publish<EventWashingGameOverData>(new EventWashingGameOverData());
}
private void AllGameOver(EventWashingAllGameOverData data)
{
if (panel != null)
{
panel.ShowForAllGameOver();
}
}
#endregion
#region
public override void InitGame(string name)
{
base.InitGame(name);
int count = m_OperatedItems.Count;
for (int i = 0; i < count; i++)
{
m_OperatedItems[i].InitStuff();
}
m_IsGuiding = true;
}
public async override void EnterGame()
{
base.EnterGame();
m_IsUpdateBatteryInfo = true;
// 打开页面(UI)
GameObject pannelObj = await UIManager.Instance.ShowUI(UITypes.EventWashingPanel);
panel = pannelObj.transform.GetComponent<EventWashingPanel>();
InitPanel();
InitEvent();
AfterEnterGame();
CheckIsOver();
}
protected override void Update()
{
base.Update();
UpdatePanelProgress();
if (m_IsGuiding == true) return;
//bool showPowerConsumption = false;
Vector2 screenPosition = Vector2.zero;
if (m_OperatedItems != null && m_Tool != null)
{
if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
{
screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
bool needChange = false;
if (m_CurOperatedItem != null)
{
if (hit.transform != m_CurOperatedItem.transform)
needChange = true;
}
else
{
needChange = true;
}
if (needChange)
{
if (m_Status == EventWashingActionStatus.Executing)
{
ChangeState2InvalidFromExecuting();
}
else if (m_Status == EventWashingActionStatus.Preparing)
{
ChangeState2InvalidFromPreparing();
}
m_CurOperatedItem = null;
int count = m_OperatedItems.Count;
for (int i = 0; i < count; i++)
{
if (hit.transform == m_OperatedItems[i].transform)
{
m_CurOperatedItem = m_OperatedItems[i];
if (!m_CurOperatedItem.IsOver())
{
m_Tool.PrepareAction(m_OperationAreas[i].transform, OperatingToolsReadyAction);
m_Status = EventWashingActionStatus.Preparing;
}
}
}
}
//if (m_CurOperatedItem != null)
//{
// if (hit.transform == m_CurOperatedItem.transform)
// showPowerConsumption = true;
//}
}
}
else
{
if (m_Status == EventWashingActionStatus.Executing)
{
ChangeState2InvalidFromExecuting();
}
else if (m_Status == EventWashingActionStatus.Preparing)
{
ChangeState2InvalidFromPreparing();
}
else
{
ChangeState2Invalid();
}
m_CurOperatedItem = null;
}
}
//if (showPowerConsumption)
//{
// SetGestureFollowPosition(screenPosition);
//}
//else
//{
// // 隐藏电量消耗
// HideElectricityConsumption();
//}
}
protected override void PauseGame()
{
base.PauseGame();
StopAllItemAction();
}
public override void SyncData()
{
SyncGameData();
base.SyncData();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 67e9488364805c944becdae7b7082d9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,124 @@
using asap.core;
using cfg;
using Cinemachine;
using GameCore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class WashingGameReview : WashingGameBase
{
#region
private EventWashingPanel panel;
private void InitPanel()
{
panel.SetDataManager(m_DataManager);
if (m_DataManager.HaveNextEventStep())
{
panel.ShowForShipOver();
}
else
{
m_DataManager.WashingData.IsAllGameOver = true;
panel.ShowForAllGameOver();
}
// 设置预览按钮
panel.SetBtnPreviewClickListener(null);
bool have = m_DataManager.HaveNextEventStep();
bool haveNextEventStep = false;
if (m_DataManager != null && m_DataManager.WashingData != null)
haveNextEventStep = m_DataManager.HaveNextEventStep();
// 设置关闭按钮
panel.SetBtnCloseClickListener(haveNextEventStep ? GoToNextStep : OnBtnCloseClickListener);
// 关闭笔刷填充进度
panel.ResetBrushChannelCounterFillAndInverse(false, false);
m_IsGuiding = panel.InitGuidance();
}
private void GoToNextStep()
{
GContext.Publish(new RewardPanelClose());
}
private void OnBtnCloseClickListener()
{
// 关闭当前Act
GContext.Publish(new UnloadActToNextAct());
}
#endregion
#region
public override void InitGame(string name)
{
base.InitGame(name);
this.m_GameType = EventWashingOperation.Review;
}
public async override void EnterGame()
{
base.EnterGame();
// 打开页面(UI)
GameObject pannelObj = await UIManager.Instance.ShowUI(UITypes.EventWashingPanel);
panel = pannelObj.transform.GetComponent<EventWashingPanel>();
InitPanel();
if (m_CameraMoveController != null)
{
m_CameraMoveController.enabled = true;
}
AfterEnterGame();
}
public override void ResetAndInitData(CinemachineVirtualCamera virtualCamera, CameraFollowPathMoveController cameraFollowPathMoveController, OperatingToolsBase tool)
{
if (virtualCamera != null)
{
m_VirtualCamera = virtualCamera;
if (m_CameraFocusedTransform != null)
{
m_VirtualCamera.LookAt = m_CameraFocusedTransform;
}
}
if (cameraFollowPathMoveController != null && m_CameraPath != null && m_RestIndexList != null)
{
m_CameraMoveController = cameraFollowPathMoveController;
m_CameraMoveController.ResetAndInit(m_CameraPath, m_RestIndexList, m_MagneticDistance);
if (m_CameraMoveController.Path.Looped == true)
{
m_CameraMoveController.IsAlwaysMoving = true;
}
m_CameraMoveController.Speed = m_CameraSpeed;
}
}
public override void GameOver()
{
if (m_CameraMoveController.Path.Looped == true)
{
m_CameraMoveController.IsAlwaysMoving = false;
}
base.GameOver();
}
protected override void Update()
{
base.Update();
if (panel != null)
panel.ContinuousOperation();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e5321f6655c699246bc2db24150192aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
using cfg;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class WashingGameSprayFoam : WashingGamePainting
{
#region
protected override void StartConclusion(EventWashingConclusionData data)
{
if (m_PaintTexture != null)
{
SetPaintTextureColor(Color.white, true);
}
base.StartConclusion(data);
}
#endregion
#region
protected override void InitPanel()
{
base.InitPanel();
// 关闭笔刷填充进度
panel.ResetBrushChannelCounterFillAndInverse(false, true);
this.StartCoroutine(StartCountingFill());
}
private IEnumerator StartCountingFill()
{
int index = 0;
while (index < 10)
{
yield return null;
index++;
}
panel.StartCountingFill();
}
#endregion
#region
public override void InitGame(string name)
{
base.InitGame(name);
this.m_GameType = EventWashingOperation.Foaming;
}
public override void Fresh(EventWashingDataManager dataManager)
{
SetPaintTextureColor(new Color(1f, 1f, 1f, 0f));
ChangePaintSphereBlendModeToAdditiveSoft();
m_PainterColor = Color.white;
base.Fresh(dataManager);
if (m_PaintTexture != null) m_PaintTexture.gameObject.SetActive(true);
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0b2cf5d1fcdb11489a05cce00298a9d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using cfg;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace game
{
public class WashingGameUnload : WashingGameRemove
{
#region
public override void InitGame(string name)
{
base.InitGame(name);
this.m_GameType = EventWashingOperation.Removing;
this.m_Status = EventWashingActionStatus.Invalid;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c081c9ecb65070942861e6aad4dd6e57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,472 @@
using asap.core;
using cfg;
using Cinemachine;
using GameCore;
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
namespace game
{
public class WashingGameVacuumCleaner : WashingGameBase
{
[Tooltip("清洁区域")]
[SerializeField]
private List<StuffCleaningArea> m_CleaningAreas = new List<StuffCleaningArea>();
[Tooltip("垃圾")]
[SerializeField]
private List<StuffTrash> m_Trashes = new List<StuffTrash>();
[Tooltip("屏幕点坐标偏移")]
[SerializeField] private Vector2 m_Offset = Vector2.zero;
[Tooltip("垃圾消失时间")]
[SerializeField] private float m_TrashDisappearTime = 0.1f;
[Tooltip("垃圾消失距离")]
[SerializeField] private float m_TrashDisappearDistance = 0.1f;
#region
private EventWashingPanel panel;
private void InitPanel()
{
panel.SetDataManager(m_DataManager);
if (m_DataManager.WashingData.IsAllGameOver == true)
{
panel.ShowForAllGameOver();
// 设置关闭按钮
panel.SetBtnCloseClickListener(OnBtnCloseClickListener);
return;
}
panel.ShowForCleaning();
// 设置预览按钮
panel.SetBtnPreviewClickListener(null);
// 设置关闭按钮
panel.SetBtnCloseClickListener(OnBtnCloseClickListener);
m_IsGuiding = panel.InitGuidance();
}
private void HideElectricityConsumption()
{
if (panel == null) return;
panel.SetElectricityConsumptionVisible(false);
}
private void ShowElectricityConsumption()
{
panel.SetElectricityConsumptionVisible(true);
}
private void SetGestureFollowPosition(Vector2 position, float time = 0.1f)
{
if (panel == null) return;
ShowElectricityConsumption();
//Vector3 worldPosition = Vector3.zero;
RectTransformUtility.ScreenPointToWorldPointInRectangle(
panel.gestureFollow.transform.GetComponent<RectTransform>(),
position,
UIManager.Instance.UICanvas.worldCamera,
out Vector3 worldPosition);
panel.SetGestureFollowPosition(worldPosition);
}
private void OnBtnCloseClickListener()
{
// 关闭当前Act
GContext.Publish(new UnloadActToNextAct());
}
private bool m_HasPublishConclusion = false;
private void UpdatePanelProgress()
{
if (panel != null)
{
float progress = CleaningProgress;
panel.UpdateSingleProgress(progress);
if (m_DataManager != null) m_DataManager.WashingData.Percent = progress;
if (progress >= 0.999f)
{
if (m_HasPublishConclusion == false)
{
if (m_DataManager != null)
{
m_DataManager.WashingData.Percent = 1f;
m_DataManager.WashingData.IsOver = true;
m_DataManager.SyncData();
}
FishingYachtAct.Publish<EventWashingConclusionData>(new EventWashingConclusionData());
m_HasPublishConclusion = true;
}
}
else
{
m_HasPublishConclusion = false;
}
}
}
public float CleaningProgress
{
get
{
int count = m_Trashes.Count;
int num = 0;
EventWashingData washingData = null;
if (m_DataManager != null) washingData = m_DataManager.WashingData;
for (int i = 0; i < count; ++i)
{
if (m_Trashes[i].IsOver())
{
num += 1;
if (washingData != null) washingData.StepItems[i] = 1f;
}
else
{
if (washingData != null) washingData.StepItems[i] = 0f;
}
}
return (float)num / count;
}
}
#endregion
#region
private void StopAllTrashesAction()
{
int count = m_Trashes.Count;
for (int i = 0; i < count; ++i)
{
m_Trashes[i].StopAction();
}
}
private void ResumeAllTrashesAction()
{
int count = m_Trashes.Count;
for (int i = 0; i < count; ++i)
{
m_Trashes[i].StartAction(null);
}
}
#endregion
#region &
public override void ResetAndInitData(CinemachineVirtualCamera virtualCamera, CameraFollowPathMoveController cameraFollowPathMoveController, OperatingToolsBase tool)
{
base.ResetAndInitData(virtualCamera, cameraFollowPathMoveController, tool);
if (tool != null)
{
int count = m_Trashes.Count;
for (int i = 0; i < count; i++)
{
var trash = m_Trashes[i];
trash.SetCleaner((ToolForFollowerAndNormalPosition)tool, ((ToolForFollowerAndNormalPosition)tool).RangeCoverage, m_TrashDisappearTime, OnTrashItemCompleteAction);
}
}
}
private void OnTrashItemCompleteAction(StuffTrash stuffTrash)
{
if (m_DataManager == null) return;
EventWashingData washingData = m_DataManager.WashingData;
int count = m_Trashes.Count;
for (int i = 0; i < count; ++i)
{
if (m_Trashes[i] == stuffTrash)
{
washingData.StepItems[i] = 1f;
break;
}
}
m_DataManager.SyncData();
}
public static float ScaleFactor
{
get
{
var dpi = Screen.dpi;
if (dpi <= 0)
{
dpi = 200.0f;
}
return 200.0f / dpi;
}
}
protected void CheckIsOver()
{
float progress = CleaningProgress;
panel.UpdateSingleProgress(progress);
if (m_DataManager != null) m_DataManager.WashingData.Percent = progress;
if (progress >= 0.999f)
{
if (m_HasPublishConclusion == false)
{
if (m_DataManager != null)
{
m_DataManager.WashingData.Percent = 1f;
m_DataManager.WashingData.IsOver = true;
m_DataManager.SyncData();
}
FishingYachtAct.Publish<EventWashingConclusionData>(new EventWashingConclusionData());
m_HasPublishConclusion = true;
}
}
}
#endregion
#region
private void InitEvent()
{
this.Subscribe<EventWashingConclusionData>(StartConclusion);
this.Subscribe<EventWashingStepOverData>(StepOver);
this.Subscribe<EventWashingAllGameOverData>(AllGameOver);
this.Subscribe<EventWashingTokenUpdateData>(UpdateBatteryInfo);
GContext.OnEvent<AddIndexEvent>().Subscribe(GuideListener).AddTo(this.disposables);
}
private void GuideListener(AddIndexEvent addIndexEvent)
{
if (addIndexEvent.CompleteGuide == true && panel != null)
{
panel.CompleteGuidance();
m_IsGuiding = false;
}
}
private bool m_IsUpdateBatteryInfo = true;
private void UpdateBatteryInfo(EventWashingTokenUpdateData data)
{
if (panel != null && m_IsUpdateBatteryInfo == true)
{
panel.SetBatteryInfo();
}
}
protected virtual void StartConclusion(EventWashingConclusionData data)
{
panel.StartConclusion();
}
private void StepOver(EventWashingStepOverData data)
{
m_IsUpdateBatteryInfo = false;
GameOver();
FishingYachtAct.Publish<EventWashingGameOverData>(new EventWashingGameOverData());
}
private void AllGameOver(EventWashingAllGameOverData data)
{
if (panel != null)
{
panel.ShowForAllGameOver();
}
}
#endregion
#region
private void SyncGameData()
{
if (m_DataManager == null) return;
EventWashingData washingData = m_DataManager.WashingData;
bool syncData = false;
int count = m_Trashes.Count;
if (washingData.StepItems.Count == 0 && washingData.Percent == 0f && washingData.IsOver == false)
{
for (int i = 0; i < count; i++)
{
washingData.StepItems.Add(0f);
m_Trashes[i].gameObject.SetActive(true);
}
syncData = true;
}
else
{
for (int i = 0; i < count; i++)
{
if (washingData.StepItems.Count == i)
{
washingData.StepItems.Add(0f);
m_Trashes[i].gameObject.SetActive(true);
syncData = true;
}
else if (washingData.StepItems[i] >= 1f)
{
m_Trashes[i].SetStatus(EventWashingActionStatus.Ending);
m_Trashes[i].gameObject.SetActive(false);
}
else
{
m_Trashes[i].SetStatus(EventWashingActionStatus.Invalid);
m_Trashes[i].gameObject.SetActive(true);
}
}
}
if (syncData) m_DataManager.SyncData();
}
protected override void SetEnergyEnough()
{
base.SetEnergyEnough();
if (panel != null) panel.SetEnergyEnough();
}
protected override void SetEnergyShortage()
{
base.SetEnergyShortage();
if (panel != null) panel.SetEnergyShortage();
}
#endregion
#region
public override void InitGame(string name)
{
base.InitGame(name);
this.m_GameType = EventWashingOperation.Cleaning;
m_IsGuiding = true;
}
public async override void EnterGame()
{
base.EnterGame();
m_IsUpdateBatteryInfo = true;
// 打开页面(UI)
GameObject pannelObj = await UIManager.Instance.ShowUI(UITypes.EventWashingPanel);
panel = pannelObj.transform.GetComponent<EventWashingPanel>();
InitPanel();
InitEvent();
AfterEnterGame();
CheckIsOver();
}
protected override void Update()
{
base.Update();
if (m_Tool == null) return;
int count = m_CleaningAreas.Count;
if (count < 1) return;
UpdatePanelProgress();
if (m_IsGuiding == true) return;
bool showPowerConsumption = false;
Vector2 screenPosition = Vector2.zero;
if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
{
screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y) + m_Offset * ScaleFactor;
Ray ray = Camera.main.ScreenPointToRay(screenPosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
for (int i = 0; i < count; i++)
{
if (hit.transform == m_CleaningAreas[i].transform)
{
if (!IsGameOver() && (HaveEnergy() || ConsumeTokens(1)))
{
var normal = hit.normal;
var point = hit.point;
((ToolForFollowerAndNormalPosition)m_Tool).Follow(point, normal);
showPowerConsumption = true;
}
}
}
}
}
if (showPowerConsumption)
{
SetGestureFollowPosition(screenPosition);
m_Tool.StartExecuting();
}
else
{
// 隐藏电量消耗
HideElectricityConsumption();
m_Tool.StopExecuting();
}
}
protected override void PauseGame()
{
base.PauseGame();
StopAllTrashesAction();
}
protected override void ResumeGame()
{
base.ResumeGame();
ResumeAllTrashesAction();
}
public override void Fresh(EventWashingDataManager dataManager)
{
base.Fresh(dataManager);
int count = m_CleaningAreas.Count;
for (int i = 0;i < count;i++)
{
m_CleaningAreas[i].gameObject.SetActive(true);
}
//count = m_Trashes.Count;
//for (int i = 0; i < count; i++)
//{
// m_Trashes[i].gameObject.SetActive(true);
//}
m_HasPublishConclusion = false;
}
public override void GameOver()
{
base.GameOver();
int count = m_CleaningAreas.Count;
for (int i = 0; i < count; i++)
{
m_CleaningAreas[i].gameObject.SetActive(false);
}
count = m_Trashes.Count;
for (int i = 0; i < count; i++)
{
m_Trashes[i].gameObject.SetActive(false);
}
}
public override void SyncData()
{
SyncGameData();
base.SyncData();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c4f71b5f1424f3b459b3f2e3dee1a429
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using game;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WashingGameCollection : MonoBehaviour
{
[Tooltip("游戏类型")]
public List<WashingGameBase> m_GameList = new List<WashingGameBase>();
#region
public List<WashingGameBase> GameList { get { return m_GameList; } }
#endregion
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 20174204770da1140ab2ab5822335d33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: