备份CatanBuilding瘦身独立工程
This commit is contained in:
27
Assets/Scripts/EventPinball/Calculate.cs
Normal file
27
Assets/Scripts/EventPinball/Calculate.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Calculate : MonoBehaviour
|
||||
{
|
||||
public float Height = 1;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
// 按下tab键,计算掉落用时
|
||||
if (Input.GetKey(KeyCode.Tab))
|
||||
{
|
||||
float g = Mathf.Abs(Physics2D.gravity.y);
|
||||
float t2 = 2 * Height / g;
|
||||
float t = Mathf.Sqrt(t2);
|
||||
Debug.Log("从高度 " + Height + " 米掉落,耗时 " + t + "s");
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/Calculate.cs.meta
Normal file
11
Assets/Scripts/EventPinball/Calculate.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cc79bb8cfbcf4d4cbd3902fa93772fc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/EventPinball/MeasureSpriteRendererSize.cs
Normal file
18
Assets/Scripts/EventPinball/MeasureSpriteRendererSize.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(SpriteRenderer))]
|
||||
public class MeasureSpriteRendererSize : MonoBehaviour
|
||||
{
|
||||
void Update()
|
||||
{
|
||||
// 按下空格键测量精灵的大小
|
||||
if (Input.GetKey(KeyCode.M))
|
||||
{
|
||||
var spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
|
||||
float boundX = spriteRenderer.bounds.size.x;
|
||||
Debug.Log("Sprite " + this.gameObject.name + " size: " + spriteRenderer.bounds.size.ToString("F2"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 987a607c41d3ecb43b2dfb3f2fe85bbb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/EventPinball/ParticleSystem.meta
Normal file
8
Assets/Scripts/EventPinball/ParticleSystem.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c01c52b71f8ce8743bb4747e93435737
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
[RequireComponent(typeof(ParticleSystem))]
|
||||
public class ParticleLayerController : MonoBehaviour
|
||||
{
|
||||
[Header("Renderer")]
|
||||
[SerializeField] private Renderer m_ParentRenderer;
|
||||
[SerializeField] private int m_SortingOrder = 100;
|
||||
|
||||
private Renderer m_Renderer;
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
// 获取或添加粒子系统
|
||||
var particleSystem = GetComponent<ParticleSystem>();
|
||||
var m_Renderer = particleSystem.GetComponent<Renderer>();
|
||||
|
||||
// 设置排序层级
|
||||
m_Renderer.sortingLayerName = m_ParentRenderer.sortingLayerName;
|
||||
m_Renderer.renderingLayerMask = m_ParentRenderer.renderingLayerMask;
|
||||
m_Renderer.sortingOrder = m_SortingOrder;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (m_Renderer != null)
|
||||
{
|
||||
m_Renderer.sortingOrder = m_SortingOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5428880f000d05a44a0c833790098c15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
38
Assets/Scripts/EventPinball/PinballCircularProgress.cs
Normal file
38
Assets/Scripts/EventPinball/PinballCircularProgress.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballCircularProgress : MonoBehaviour
|
||||
{
|
||||
#region progress 相关
|
||||
private float m_Progress = 0f;
|
||||
public void SetProgress(float progress)
|
||||
{
|
||||
m_Progress = progress;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
private Material m_Material;
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
var renderer = GetComponent<SpriteRenderer>();
|
||||
m_Material = renderer.material;
|
||||
|
||||
m_Progress = 0f;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (m_Material != null)
|
||||
{
|
||||
m_Material.SetFloat("_Progress", m_Progress);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballCircularProgress.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballCircularProgress.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0e650905608528419f710d539fa88b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
428
Assets/Scripts/EventPinball/PinballFiringPin.cs
Normal file
428
Assets/Scripts/EventPinball/PinballFiringPin.cs
Normal file
@@ -0,0 +1,428 @@
|
||||
using asap.core;
|
||||
using Game;
|
||||
using GameCore;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballFiringPin : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Collider2D m_Collider2D;
|
||||
[SerializeField] private PinballPellet m_PelletBase;
|
||||
|
||||
private EventPinballDataManager m_DataManager;
|
||||
|
||||
private PinballPellet m_Pellet;
|
||||
|
||||
private void CreateNewPellet()
|
||||
{
|
||||
if (m_PelletBase.gameObject.activeSelf == true)
|
||||
{
|
||||
m_PelletBase.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (m_Pellet != null)
|
||||
{
|
||||
GameObject tmp = m_Pellet.gameObject;
|
||||
tmp.SetActive(false);
|
||||
GameObject.Destroy(tmp);
|
||||
m_Pellet = null;
|
||||
}
|
||||
GameObject gameObject = Instantiate(m_PelletBase.gameObject, m_PelletBase.transform.position, m_PelletBase.transform.rotation, m_PelletBase.transform.parent);
|
||||
m_Pellet = gameObject.GetComponent<PinballPellet>();
|
||||
m_Pellet.gameObject.SetActive(true);
|
||||
m_Pellet.InitPellet(m_RecordTimes);
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballSetDummyPelletData()
|
||||
{
|
||||
Pellet = m_Pellet
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#region 声音相关
|
||||
[Header("声音设置")]
|
||||
[SerializeField] private AudioClip m_FiringPinPullAudioClip;
|
||||
[SerializeField] private AssetReferenceT<AudioClip> m_FiringPinSpringAudioClip;
|
||||
private Sound m_FiringPinPullSound;
|
||||
public void PlayPullSound()
|
||||
{
|
||||
if (m_FiringPinPullSound != null)
|
||||
{
|
||||
m_FiringPinPullSound.audioSource.Play();
|
||||
}
|
||||
}
|
||||
public void PlaySpringSound()
|
||||
{
|
||||
if (m_FiringPinPullSound != null)
|
||||
{
|
||||
m_FiringPinPullSound.audioSource.Stop();
|
||||
}
|
||||
|
||||
GContext.Publish(new AssetReferenceAudioClip(m_FiringPinSpringAudioClip, time: 0f));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 撞针操作
|
||||
[Header("开关设置")]
|
||||
[SerializeField] private Transform m_InitialTransform;
|
||||
[SerializeField] private Transform m_FarthestTransform;
|
||||
[SerializeField] private float m_ReturnSpeed = 50f; // 回弹速度
|
||||
[SerializeField] private float m_DeferTime = 0.1f;
|
||||
[SerializeField] private float m_ProtectedRatio = 0.1f;
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
[Header("物理设置/模拟数据设置")]
|
||||
[SerializeField] private float m_MinForce = 7f;
|
||||
[SerializeField] private float m_ForceStep = 0.0001f;
|
||||
//#endif
|
||||
|
||||
private float m_MaxDragDistance = 0f; // 最大拖动距离
|
||||
private float m_MaxDragDistancePositive = 0f; // 最大拖动距离
|
||||
private Vector3 m_InitialPosition; // 初始位置
|
||||
private Vector3 m_FarthestPosition; // 最远位置
|
||||
private bool isDragging = false; // 拖动状态
|
||||
private float m_LastTouchDownTime = -1f;
|
||||
private Camera mainCamera; // 主摄像机
|
||||
|
||||
private void OnMouseDown()
|
||||
{
|
||||
isDragging = true;
|
||||
m_LastTouchDownTime = Time.time;
|
||||
|
||||
PlayPullSound();
|
||||
}
|
||||
|
||||
private void OnMouseDrag()
|
||||
{
|
||||
if (!isDragging) return;
|
||||
|
||||
// 将屏幕坐标转为世界坐标
|
||||
Vector3 touchPos = mainCamera.ScreenToWorldPoint(Input.mousePosition);
|
||||
touchPos.x = m_InitialPosition.x;
|
||||
touchPos.z = m_InitialPosition.z; // 保持Z轴不变
|
||||
|
||||
// 计算允许移动的位置
|
||||
Vector3 targetPos = m_InitialPosition;
|
||||
float deltaY = Mathf.Clamp(
|
||||
touchPos.y - m_InitialPosition.y,
|
||||
m_MaxDragDistance,
|
||||
0f
|
||||
);
|
||||
targetPos.y = m_InitialPosition.y + deltaY;
|
||||
|
||||
transform.position = targetPos;
|
||||
|
||||
float ratio = GetDragRatio();
|
||||
FishingPinballAct.Publish(new EventPinballEnergyArrowData()
|
||||
{
|
||||
Energy = ratio
|
||||
});
|
||||
|
||||
FishingPinballAct.Publish<EventPinballSpringUpdateData>(new EventPinballSpringUpdateData()
|
||||
{
|
||||
Ratio = 1.0f - ratio
|
||||
});
|
||||
}
|
||||
|
||||
private void OnMouseUp()
|
||||
{
|
||||
if (isDragging == false)
|
||||
{
|
||||
FishingPinballAct.Publish(new EventPinballEnergyArrowRestoreData());
|
||||
return;
|
||||
}
|
||||
|
||||
isDragging = false;
|
||||
|
||||
StartCoroutine(BounceBack());
|
||||
}
|
||||
|
||||
public float GetDragRatio()
|
||||
{
|
||||
Vector3 startPos = transform.position;
|
||||
|
||||
float deadzone = m_MaxDragDistancePositive * m_ProtectedRatio;
|
||||
|
||||
float distance = Mathf.Abs(startPos.y - m_InitialPosition.y) - deadzone;
|
||||
if (distance <= 0f) return 0f;
|
||||
|
||||
float totalDistance = m_MaxDragDistancePositive - deadzone;
|
||||
if (totalDistance <= 0f) return 0f;
|
||||
|
||||
return distance / totalDistance;
|
||||
}
|
||||
|
||||
private void ShowChainPack()
|
||||
{
|
||||
if (GContext.container.Resolve<FishingEventData>().ChainPackWithProgressMigrationData.IsChainPackDepleted)
|
||||
{
|
||||
ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_103"));
|
||||
}
|
||||
GContext.container.Resolve<FishingEventData>().ChainPackWithProgressMigrationData.ShowChainPack();
|
||||
}
|
||||
|
||||
IEnumerator BounceBack()
|
||||
{
|
||||
float elapsed = 0f;
|
||||
Vector3 startPos = transform.position;
|
||||
|
||||
float ratio = GetDragRatio();
|
||||
|
||||
while (elapsed < 1f)
|
||||
{
|
||||
elapsed += m_ReturnSpeed * Time.deltaTime;
|
||||
// 使用缓动函数实现弹性
|
||||
transform.position = Vector3.Lerp(
|
||||
startPos,
|
||||
m_InitialPosition,
|
||||
Mathf.SmoothStep(0, 1, elapsed)
|
||||
);
|
||||
|
||||
float tmpRatio = GetDragRatio();
|
||||
|
||||
FishingPinballAct.Publish<EventPinballSpringUpdateData>(new EventPinballSpringUpdateData()
|
||||
{
|
||||
Ratio = 1.0f - tmpRatio
|
||||
});
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
float tmpLastTouchDownTime = m_LastTouchDownTime;
|
||||
|
||||
m_LastTouchDownTime = -1f;
|
||||
|
||||
if (ratio <= 0f)
|
||||
{
|
||||
FishingPinballAct.Publish(new EventPinballEnergyArrowRestoreData());
|
||||
yield break;
|
||||
}
|
||||
|
||||
|
||||
if (tmpLastTouchDownTime < 0f)
|
||||
{
|
||||
FishingPinballAct.Publish(new EventPinballEnergyArrowRestoreData());
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (Time.time - tmpLastTouchDownTime < m_DeferTime)
|
||||
{
|
||||
FishingPinballAct.Publish(new EventPinballEnergyArrowRestoreData());
|
||||
yield break;
|
||||
}
|
||||
|
||||
PlaySpringSound();
|
||||
|
||||
if (m_IsPelletRunning)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var dataManager = GContext.container.Resolve<EventPinballDataManager>();
|
||||
|
||||
//dataManager.InitGameRound();
|
||||
|
||||
if (!dataManager.ConsumeTemporaryTokensDefault())
|
||||
{
|
||||
FishingPinballAct.Publish(new EventPinballEnergyArrowRestoreData());
|
||||
|
||||
ShowChainPack();
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (m_DataManager != null)
|
||||
{
|
||||
m_DataManager.IsSimulatorMode = m_IsSimulatorMode;
|
||||
}
|
||||
|
||||
//CreateNewPellet();
|
||||
|
||||
//float force = Mathf.Lerp(m_MinForce, m_MaxForce, ratio);
|
||||
float force = dataManager.GetRandomForce(ratio);
|
||||
m_Pellet.LaunchPellet(force, m_RecordTimes);
|
||||
FishingPinballAct.Publish(new EventPinballEnergyArrowRestoreData());
|
||||
|
||||
//#if AGG
|
||||
// using (var e = GEvent.GameEvent("event_pinball"))
|
||||
// {
|
||||
// e.AddContent("force", force)
|
||||
// .AddContent("item_consume", m_DataManager.TemporaryConsumedToken);
|
||||
// }
|
||||
//#endif
|
||||
}
|
||||
|
||||
bool IsTouchingSwitch(Vector2 screenPos)
|
||||
{
|
||||
RaycastHit2D hit = Physics2D.Raycast(
|
||||
mainCamera.ScreenToWorldPoint(screenPos),
|
||||
Vector2.zero
|
||||
);
|
||||
return hit.collider != null && hit.collider.gameObject == gameObject;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 运行模式相关(模拟数据模式/正常玩家模式)
|
||||
[SerializeField] private bool m_IsSimulatorMode = false;
|
||||
[SerializeField] private bool m_IsProcessingSimulatedData = false;
|
||||
private int m_RecordTimes = 0;
|
||||
#endregion
|
||||
|
||||
#region 事件相关
|
||||
private void InitEvent()
|
||||
{
|
||||
FishingPinballAct.Subscribe<EventPinballResetPelletStatusData>(ResetPelletInFiringPin);
|
||||
FishingPinballAct.Subscribe<EventPinballLaunchPelletStatusData>(LaunchPelletInFiringPin);
|
||||
FishingPinballAct.Subscribe<EventPinballResumePelletData>(ResumePellet);
|
||||
FishingPinballAct.Subscribe<EventPinballLaunchPelletData>(OnLaunchPelletDataEvent);
|
||||
}
|
||||
public void ResumePellet(EventPinballResumePelletData data)
|
||||
{
|
||||
CreateNewPellet();
|
||||
float force = m_MinForce + m_ForceStep * m_RecordTimes;
|
||||
|
||||
m_Pellet.ResumePellet(force, m_RecordTimes);
|
||||
|
||||
if (m_IsProcessingSimulatedData)
|
||||
{
|
||||
m_RecordTimes++;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnLaunchPelletDataEvent(EventPinballLaunchPelletData data)
|
||||
{
|
||||
if (data == null) return;
|
||||
if (m_Pellet != null)
|
||||
{
|
||||
m_Pellet.LaunchPellet(data.Force, m_RecordTimes);
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_IsPelletRunning = false;
|
||||
public void LaunchPelletInFiringPin(EventPinballLaunchPelletStatusData data)
|
||||
{
|
||||
m_IsPelletRunning = true;
|
||||
}
|
||||
public void ResetPelletInFiringPin(EventPinballResetPelletStatusData data)
|
||||
{
|
||||
m_IsPelletRunning = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
m_DataManager = GContext.container.Resolve<EventPinballDataManager>();
|
||||
|
||||
m_InitialPosition = m_InitialTransform.position;
|
||||
m_FarthestPosition = m_FarthestTransform.position;
|
||||
|
||||
m_MaxDragDistance = m_FarthestTransform.position.y - m_InitialPosition.y;
|
||||
m_MaxDragDistancePositive = Mathf.Abs(m_MaxDragDistance);
|
||||
|
||||
mainCamera = Camera.main;
|
||||
m_LastTouchDownTime = -1f;
|
||||
|
||||
m_FiringPinPullSound = GContext.container.Resolve<ISoundService>().GetNewUISound(m_FiringPinPullAudioClip);
|
||||
|
||||
m_IsSimulatorMode = false;
|
||||
m_IsPelletRunning = false;
|
||||
|
||||
InitEvent();
|
||||
|
||||
CreateNewPellet();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (m_Collider2D == null) return;
|
||||
|
||||
bool isTriggered = false, isDown = false, isDrag = false, isUp = false;
|
||||
Vector2 screenPosition = Vector2.zero;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (Input.GetKeyUp(KeyCode.F1))
|
||||
{
|
||||
if (m_DataManager != null)
|
||||
{
|
||||
m_DataManager.IsSimulatorMode = m_IsSimulatorMode;
|
||||
}
|
||||
//CreateNewPellet();
|
||||
m_Pellet.InitPellet(m_RecordTimes);
|
||||
//m_Pellet.ResetPellet();
|
||||
m_Pellet.SetState(EventPinballState.Prepare);
|
||||
m_Pellet.LaunchPellet(m_MinForce, m_RecordTimes);
|
||||
return;
|
||||
}
|
||||
else if (Input.GetKeyUp(KeyCode.F2))
|
||||
{
|
||||
FishingPinballAct.Publish(new EventPinballResumePelletData());
|
||||
return;
|
||||
}
|
||||
|
||||
isDown = Input.GetMouseButtonDown(0);
|
||||
isDrag = Input.GetMouseButton(0);
|
||||
isUp = Input.GetMouseButtonUp(0);
|
||||
|
||||
screenPosition = Input.mousePosition;
|
||||
|
||||
isTriggered = isDown || isDrag || isUp;
|
||||
#elif UNITY_IOS || UNITY_ANDROID
|
||||
isTriggered = Input.touchCount > 0;
|
||||
|
||||
if (isTriggered)
|
||||
{
|
||||
Touch touch = Input.GetTouch(0);
|
||||
screenPosition = touch.position;
|
||||
switch (touch.phase)
|
||||
{
|
||||
case TouchPhase.Began:
|
||||
{
|
||||
isDown = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case TouchPhase.Moved:
|
||||
{
|
||||
isDrag = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case TouchPhase.Ended:
|
||||
{
|
||||
isUp = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isTriggered && IsTouchingSwitch(screenPosition))
|
||||
{
|
||||
if (isDown)
|
||||
{
|
||||
OnMouseDown();
|
||||
}
|
||||
else if (isUp)
|
||||
{
|
||||
OnMouseUp();
|
||||
}
|
||||
else if (isDrag)
|
||||
{
|
||||
OnMouseDrag();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnMouseUp();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballFiringPin.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballFiringPin.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4292a8fbe68596a44b853f6ee9bc8d5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
690
Assets/Scripts/EventPinball/PinballPellet.cs
Normal file
690
Assets/Scripts/EventPinball/PinballPellet.cs
Normal file
@@ -0,0 +1,690 @@
|
||||
using asap.core;
|
||||
using Game;
|
||||
using GameCore;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
namespace game
|
||||
{
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
public class PinballPellet : MonoBehaviour
|
||||
{
|
||||
[Header("物理设置")]
|
||||
public float Gravity = 9.81f;
|
||||
public Rigidbody2D m_Rigidbody2D;
|
||||
|
||||
[Header("操作设置")]
|
||||
[SerializeField] private List<PinballScoringWidgetBase> m_BonusList = new List<PinballScoringWidgetBase>();
|
||||
[SerializeField] private List<PinballScoringWidgetBase> m_ExitList = new List<PinballScoringWidgetBase>();
|
||||
|
||||
#region 声音相关
|
||||
[Header("声音设置")]
|
||||
[SerializeField] private List<AssetReferenceT<AudioClip>> m_BonusSoundList = new List<AssetReferenceT<AudioClip>>();
|
||||
[SerializeField] private AssetReferenceT<AudioClip> m_CollisionSound;
|
||||
[SerializeField] private List<GameObject> m_CollisionSoundBlacklist = new List<GameObject>();
|
||||
private int m_BonusSoundIndex = 0;
|
||||
public void PlayBonusSound()
|
||||
{
|
||||
int count = m_BonusSoundList.Count;
|
||||
if (m_BonusSoundIndex >= 0 && m_BonusSoundIndex < count)
|
||||
{
|
||||
AssetReferenceT<AudioClip> bonusSound = m_BonusSoundList[m_BonusSoundIndex];
|
||||
GContext.Publish(new AssetReferenceAudioClip(bonusSound, time: 0f));
|
||||
}
|
||||
m_BonusSoundIndex++;
|
||||
}
|
||||
|
||||
public void PlayCollisionSound()
|
||||
{
|
||||
GContext.Publish(new AssetReferenceAudioClip(m_CollisionSound, time: 0f));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 分数
|
||||
public void AddScore(PinballScoringWidgetBase scoringWidget, ContactPoint2D contactPoint, bool isCumulativeResponseNumber = true)
|
||||
{
|
||||
if (scoringWidget == null) return;
|
||||
|
||||
if (isCumulativeResponseNumber)
|
||||
{
|
||||
GetDataManager().CumulativeResponseNumber++;
|
||||
}
|
||||
|
||||
// 弹出文本
|
||||
string tip = scoringWidget.GetTip();
|
||||
|
||||
EventPinballBonusType bonusType = scoringWidget.BonusType;
|
||||
int number = scoringWidget.Number;
|
||||
|
||||
FloatingText floatingText = null;
|
||||
|
||||
if (bonusType == EventPinballBonusType.TypeScore)
|
||||
{
|
||||
floatingText = FloatingTextPool.Instance.GetFloatingScoreText();
|
||||
|
||||
GetDataManager().AddTemporaryScore(number);
|
||||
|
||||
floatingText.Initialize(tip, contactPoint.point);
|
||||
}
|
||||
else if (bonusType == EventPinballBonusType.TypeMultiple)
|
||||
{
|
||||
//floatingText = FloatingTextPool.Instance.GetFloatingMultipleText();
|
||||
|
||||
GetDataManager().MultiplyTemporaryScore(number);
|
||||
|
||||
//floatingText.Initialize(tip, contactPoint.point);
|
||||
}
|
||||
|
||||
//m_PelletTrackInfo.RoutePointList.
|
||||
//string routes = string.Join("-", m_PelletTrackInfo.RoutePointList);
|
||||
//Debug.LogError("--- 类型:" + bonusType + ", times:" + m_RecordTimes + ", name:" + scoringWidget.gameObject.name + ", 增加分数:" + number + ", 当前分数:" + m_Score + ", tip:" + tip + ", count:" + m_PelletTrackInfo.RoutePointList.Count + ", routes:"+ routes);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 状态数据
|
||||
private EventPinballDataManager m_DataManager;
|
||||
public EventPinballDataManager GetDataManager()
|
||||
{
|
||||
if (m_DataManager == null)
|
||||
{
|
||||
m_DataManager = GContext.container.Resolve<EventPinballDataManager>();
|
||||
}
|
||||
return m_DataManager;
|
||||
}
|
||||
private EventPinballState m_State = EventPinballState.Prepare;
|
||||
public void SetState(EventPinballState state)
|
||||
{
|
||||
if (m_State != state)
|
||||
{
|
||||
m_State = state;
|
||||
}
|
||||
}
|
||||
public void SetBonusListToInvalid()
|
||||
{
|
||||
foreach (var item in m_BonusList)
|
||||
{
|
||||
item.SetInvalidMaterial();
|
||||
}
|
||||
}
|
||||
public void ResetBonusListToValid()
|
||||
{
|
||||
foreach (var item in m_BonusList)
|
||||
{
|
||||
item.ResetValidMaterial();
|
||||
}
|
||||
}
|
||||
public void ResetExitListToValid()
|
||||
{
|
||||
foreach (var item in m_ExitList)
|
||||
{
|
||||
item.ResetValidMaterial();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
#region CSV记录
|
||||
[Header("数据存储设置")]
|
||||
[SerializeField] private float m_MaxTime = 15f;
|
||||
[SerializeField] private List<string> m_WhiteNamePrefixList = new List<string>();
|
||||
[SerializeField] private bool m_IsProcessingSimulatedData = false;
|
||||
[SerializeField] private bool m_IsSaveTrackInfoData = false;
|
||||
|
||||
private int m_RecordTimes = 0;
|
||||
private PinballPelletTrackInfo m_PelletTrackInfo = new PinballPelletTrackInfo();
|
||||
private float m_Force = 10f;
|
||||
|
||||
private float m_CumulativeTime = 0f;
|
||||
|
||||
private static readonly object trackInfoLock = new object();
|
||||
public void ClearPelletTrackInfo(int recordTimes)
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
if (m_Rigidbody2D == null) return;
|
||||
m_PelletTrackInfo.ID = recordTimes;
|
||||
m_PelletTrackInfo.Name = this.gameObject.name;
|
||||
m_PelletTrackInfo.Force = m_Force;
|
||||
m_PelletTrackInfo.Gravity = Gravity;
|
||||
m_PelletTrackInfo.Clear();
|
||||
}
|
||||
public void SavePelletTrackInfo()
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
m_PelletTrackInfo.Score = GetDataManager().TemporaryScore;
|
||||
SavePelletTrackInfoToCsv(EventPinballConfig.CSVFileName);
|
||||
}
|
||||
public void RecordTrackInfo(List<ContactPoint2D> list, EventPinballTrackType trackType, Collision2D collision)
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
lock (trackInfoLock)
|
||||
{
|
||||
if (m_Rigidbody2D == null || list == null) return;
|
||||
|
||||
var trackNode = new PinballPelletTrackNode()
|
||||
{
|
||||
TrackType = trackType,
|
||||
ContactName = collision.gameObject.name,
|
||||
MaterialName = collision.rigidbody?.sharedMaterial?.name
|
||||
};
|
||||
|
||||
m_PelletTrackInfo.TrackNodeList.Add(trackNode);
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
TrackNodeContactPoint2D contactPoint2D = new TrackNodeContactPoint2D()
|
||||
{
|
||||
Velocity = item.relativeVelocity,
|
||||
Position = item.point
|
||||
};
|
||||
trackNode.ContactPoint2DList.Add(contactPoint2D);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void RecordEnter(Collision2D collision, List<ContactPoint2D> contactPointList)
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
if (m_Rigidbody2D == null || collision == null) return;
|
||||
|
||||
if (CheckNeedRecord(collision))
|
||||
{
|
||||
m_PelletTrackInfo.RoutePointList.Add(collision.gameObject.name);
|
||||
}
|
||||
|
||||
RecordTrackInfo(contactPointList, EventPinballTrackType.TypeEnter, collision);
|
||||
}
|
||||
public void RecordExit(Collision2D collision)
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
if (m_Rigidbody2D == null || collision == null) return;
|
||||
|
||||
List<ContactPoint2D> list = new List<ContactPoint2D>();
|
||||
collision.GetContacts(list);
|
||||
|
||||
RecordTrackInfo(list, EventPinballTrackType.TypeExit, collision);
|
||||
}
|
||||
public bool CheckNeedRecord(Collision2D collision)
|
||||
{
|
||||
if (collision == null) return false;
|
||||
|
||||
foreach (var item in m_WhiteNamePrefixList)
|
||||
{
|
||||
if (collision.gameObject.name.StartsWith(item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public IEnumerator PrepareToSavePelletTrackInfo(float force, int recordTimes)
|
||||
{
|
||||
//StaticBall();
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
|
||||
//m_PelletTrackInfo.Score = GetDataManager().TemporaryScore;
|
||||
|
||||
//SavePelletTrackInfo();
|
||||
|
||||
//StaticBall();
|
||||
yield return new WaitForSeconds(1f);
|
||||
|
||||
//StaticBall();
|
||||
|
||||
yield return new WaitForSeconds(2f);
|
||||
|
||||
ResetPellet();
|
||||
SetState(EventPinballState.Prepare);
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballResetPelletStatusData());
|
||||
|
||||
//float force = m_MinForce + m_ForceStep * m_RecordTimes;
|
||||
LaunchPellet(force, recordTimes);
|
||||
}
|
||||
#endregion
|
||||
//#endif
|
||||
|
||||
#region 轨迹记录
|
||||
private List<PinballPelletTrackInfo> m_PelletTrackInfoList = new List<PinballPelletTrackInfo>();
|
||||
|
||||
public void ClearPelletTrackInfoList()
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
foreach (var item in m_PelletTrackInfoList)
|
||||
{
|
||||
item.Clear();
|
||||
}
|
||||
m_PelletTrackInfoList.Clear();
|
||||
}
|
||||
public void AddPelletTrackInfo(PinballPelletTrackInfo pelletTrackInfo)
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
m_PelletTrackInfoList.Add(pelletTrackInfo);
|
||||
}
|
||||
public string GetPelletTrackInfoCsvHeader()
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
list.Add("id");
|
||||
list.Add("Name");
|
||||
list.Add("Force");
|
||||
list.Add("Count");
|
||||
list.Add("Multiple");
|
||||
list.Add("Score");
|
||||
list.Add("TrackInfo");
|
||||
|
||||
string header = string.Join(",", list);
|
||||
return header;
|
||||
}
|
||||
public void CreatePelletTrackInfoCsv(string filename)
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
string filapath = GetDataManager().GetSaveFilepath(filename);
|
||||
Debug.LogWarning("--- filepath:" + filapath);
|
||||
|
||||
if (!File.Exists(filapath))
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
list.Add(GetPelletTrackInfoCsvHeader());
|
||||
|
||||
PinballUtils.ExportToCSV(list, filapath);
|
||||
}
|
||||
}
|
||||
public void SavePelletTrackInfoToCsv(string filename)
|
||||
{
|
||||
if (!m_IsSaveTrackInfoData) return;
|
||||
string filapath = GetDataManager().GetSaveFilepath(filename);
|
||||
Debug.LogWarning("--- filepath:" + filapath);
|
||||
|
||||
List<string> list = new List<string>();
|
||||
|
||||
foreach (var trackInfo in m_PelletTrackInfoList)
|
||||
{
|
||||
list.Add(trackInfo.ToString());
|
||||
}
|
||||
|
||||
PinballUtils.ExportToCSV(list, filapath);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 操作相关
|
||||
private bool m_ReadyToLaunch = false;
|
||||
public void PrepareToResetPellet()
|
||||
{
|
||||
//StaticBall();
|
||||
//yield return new WaitForSeconds(2f);
|
||||
|
||||
ResetPellet();
|
||||
SetState(EventPinballState.Prepare);
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballResetPelletStatusData());
|
||||
}
|
||||
public void LaunchPellet(float force, int recordTimes)
|
||||
{
|
||||
if (m_State != EventPinballState.Prepare) return;
|
||||
|
||||
SetState(EventPinballState.Running);
|
||||
m_CumulativeTime = 0f;
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
|
||||
m_Force = force;
|
||||
|
||||
GetDataManager().PinballData.Force = force;
|
||||
|
||||
ClearPelletTrackInfo(recordTimes);
|
||||
|
||||
ClearPelletTrackInfoList();
|
||||
AddPelletTrackInfo(this.m_PelletTrackInfo);
|
||||
|
||||
//m_RecordTimes++;
|
||||
//#endif
|
||||
//Debug.LogWarning("--- LaunchPellet force:" + force + ", m_Force:" + m_Force);
|
||||
Physics2D.gravity = new Vector2(0f, -Mathf.Abs(Gravity));
|
||||
|
||||
//var dir = new Vector2(0f, 1f);
|
||||
//m_Rigidbody2D.AddForce(dir * force, ForceMode2D.Impulse);
|
||||
|
||||
m_ReadyToLaunch = true;
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballLaunchPelletStatusData());
|
||||
}
|
||||
public void ResetPellet()
|
||||
{
|
||||
GetDataManager().GetNextPinballData();
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballSwitcherOpen());
|
||||
FishingPinballAct.Publish(new EventPinballStopArrowBreathAnimData());
|
||||
FishingPinballAct.Publish(new EventPinballHideWidgetMultipleEffectData());
|
||||
FishingPinballAct.Publish(new EventPinballHideCircularRotationalAnim());
|
||||
FishingPinballAct.Publish(new EventPinballBasicScoreShowData());
|
||||
|
||||
GetDataManager().InitGameRound();
|
||||
m_BonusSoundIndex = 0;
|
||||
|
||||
ResetBonusListToValid();
|
||||
ResetExitListToValid();
|
||||
|
||||
ShowRenderer();
|
||||
|
||||
//StaticBall();
|
||||
|
||||
//this.transform.position = m_OriginalPosition;
|
||||
//this.transform.rotation = m_OriginalQuaternion;
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballResetMagnification());
|
||||
}
|
||||
public void CheckIfTriggeredBonusOver()
|
||||
{
|
||||
if (!GetDataManager().IsAddScoreValid())
|
||||
{
|
||||
FishingPinballAct.Publish(new EventPinballShowWidgetScoreEffect2Data());
|
||||
FishingPinballAct.Publish(new EventPinballPlayArrowBreathAnimData());
|
||||
FishingPinballAct.Publish(new EventPinballShowCircularRotationalAnim());
|
||||
FishingPinballAct.Publish(new EventPinballBasicScoreHideData());
|
||||
}
|
||||
}
|
||||
public bool HavePelletTriggeredBonus(Collision2D collision, List<ContactPoint2D> contactPointList, bool isAddScore)
|
||||
{
|
||||
if (collision == null || contactPointList == null || contactPointList.Count < 1) return false;
|
||||
if (this.m_State == EventPinballState.Running)
|
||||
{
|
||||
ContactPoint2D contactPoint = contactPointList[0];
|
||||
foreach (var item in m_BonusList)
|
||||
{
|
||||
if (item.gameObject == collision.gameObject)
|
||||
{
|
||||
GetDataManager().AccumulatedTriggerCount++;
|
||||
|
||||
if (isAddScore)
|
||||
{
|
||||
(item as PinballScoringWidgetScore)?.ShowEffect1();
|
||||
|
||||
AddScore(item, contactPoint);
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballShowPopupData()
|
||||
{
|
||||
Scores = GetDataManager().TemporaryScore,
|
||||
BonusType = item.BonusType,
|
||||
IsMultipleMax = false
|
||||
});
|
||||
|
||||
CheckIfTriggeredBonusOver();
|
||||
|
||||
PlayBonusSound();
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// FishingPinballAct.Publish(new EventPinballShowWidgetScoreEffect2Data());
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void CheckIfMultipleMax(int multiple)
|
||||
{
|
||||
if (multiple == EventPinballConfig.MultipleMax)
|
||||
{
|
||||
GetDataManager().IsMultipleMax = true;
|
||||
FishingPinballAct.Publish<EventPinballPlayLightOnAnimData>(new EventPinballPlayLightOnAnimData());
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDataManager().IsMultipleMax = false;
|
||||
}
|
||||
}
|
||||
public void HavePelletTriggeredExit(Collision2D collision, List<ContactPoint2D> contactPointList)
|
||||
{
|
||||
if (collision == null || contactPointList == null || contactPointList.Count < 1) return;
|
||||
if (this.m_State == EventPinballState.Running)
|
||||
{
|
||||
ContactPoint2D contactPoint = contactPointList[0];
|
||||
foreach (var item in m_ExitList)
|
||||
{
|
||||
if (item.gameObject == collision.gameObject)
|
||||
{
|
||||
GetDataManager().PinballData.Multiple = item.Number;
|
||||
(item as PinballScoringWidgetMultiple)?.ShowEffect();
|
||||
(item as PinballScoringWidgetMultiple)?.PlaySound();
|
||||
|
||||
AddScore(item, contactPoint, false);
|
||||
SetState(EventPinballState.Ended);
|
||||
CheckIfMultipleMax(item.Number);
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
m_PelletTrackInfo.Multiple = item.Number;
|
||||
SavePelletTrackInfo();
|
||||
//#endif
|
||||
FishingPinballAct.Publish(new EventPinballHideCircularRotationalAnim());
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballShowMultipleTextData()
|
||||
{
|
||||
BonusType = item.BonusType,
|
||||
Position = contactPoint.point,
|
||||
Tips = item.GetTip(),
|
||||
Scores = GetDataManager().TemporaryScore,
|
||||
IsMultipleMax = item.Number == EventPinballConfig.MultipleMax
|
||||
});
|
||||
|
||||
HideRenderer();
|
||||
//StaticBall();
|
||||
|
||||
//#if AGG
|
||||
// using (var e = GEvent.GameEvent("event_pinball_result"))
|
||||
// {
|
||||
// e.AddContent("count", GetDataManager().AccumulatedTriggerCount)
|
||||
// .AddContent("Multiple", item.Number)
|
||||
// .AddContent("point_count", GetDataManager().TemporaryScore);
|
||||
// }
|
||||
//#endif
|
||||
|
||||
//TerminatePellet(item.Number == EventPinballConfig.MultipleMax);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//public void StaticBall()
|
||||
//{
|
||||
// m_Rigidbody2D.bodyType = RigidbodyType2D.Kinematic;
|
||||
// m_Rigidbody2D.isKinematic = true;
|
||||
|
||||
// m_Rigidbody2D.Sleep();
|
||||
|
||||
// // 重置运动状态
|
||||
// m_Rigidbody2D.velocity = Vector2.zero;
|
||||
// m_Rigidbody2D.angularVelocity = 0f;
|
||||
|
||||
// // 重置约束
|
||||
// m_Rigidbody2D.freezeRotation = false; // 解除旋转锁定
|
||||
// m_Rigidbody2D.constraints = RigidbodyConstraints2D.None; // 解除所有约束
|
||||
|
||||
// // 重置碰撞检测
|
||||
// m_Rigidbody2D.simulated = true; // 确保启用物理模拟
|
||||
// m_Rigidbody2D.interpolation = RigidbodyInterpolation2D.None; // 重置插值
|
||||
|
||||
// // 重置休眠状态
|
||||
// m_Rigidbody2D.WakeUp(); // 强制唤醒刚体
|
||||
|
||||
// this.transform.position = m_OriginalPosition;
|
||||
// this.transform.rotation = m_OriginalQuaternion;
|
||||
//}
|
||||
public void ResumePellet(float force, int recordTimes)
|
||||
{
|
||||
//StaticBall();
|
||||
//this.transform.position = m_OriginalPosition;
|
||||
//this.transform.rotation = m_OriginalQuaternion;
|
||||
|
||||
if (m_IsProcessingSimulatedData)
|
||||
{
|
||||
this.StartCoroutine(PrepareToSavePelletTrackInfo(force, recordTimes));
|
||||
}
|
||||
else
|
||||
{
|
||||
//this.StartCoroutine(PrepareToResetPellet());
|
||||
PrepareToResetPellet();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Collider2D
|
||||
protected virtual void OnCollisionEnter2D(Collision2D collision)
|
||||
{
|
||||
List<ContactPoint2D> contactPointList = new List<ContactPoint2D>();
|
||||
collision.GetContacts(contactPointList);
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
RecordEnter(collision, contactPointList);
|
||||
//#endif
|
||||
|
||||
bool isTriggered = HavePelletTriggeredBonus(collision, contactPointList, GetDataManager().IsAddScoreValid());
|
||||
|
||||
if (!isTriggered)
|
||||
{
|
||||
bool isInBlacklist = false;
|
||||
foreach (var item in m_CollisionSoundBlacklist)
|
||||
{
|
||||
if (collision.gameObject == item)
|
||||
{
|
||||
isInBlacklist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isInBlacklist)
|
||||
{
|
||||
PlayCollisionSound();
|
||||
}
|
||||
}
|
||||
|
||||
HavePelletTriggeredExit(collision, contactPointList);
|
||||
}
|
||||
protected virtual void OnCollisionExit2D(Collision2D collision)
|
||||
{
|
||||
//#if UNITY_EDITOR
|
||||
RecordExit(collision);
|
||||
//#endif
|
||||
if (!GetDataManager().IsAddScoreValid())
|
||||
{
|
||||
SetBonusListToInvalid();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 显示
|
||||
[SerializeField] private SpriteRenderer m_SpriteRenderer;
|
||||
[SerializeField] private GameObject m_Trail;
|
||||
public void HideRenderer()
|
||||
{
|
||||
if (m_SpriteRenderer != null)
|
||||
{
|
||||
m_SpriteRenderer.enabled = false;
|
||||
}
|
||||
if (m_Trail != null)
|
||||
{
|
||||
m_Trail.SetActive(false);
|
||||
}
|
||||
}
|
||||
public void ShowRenderer()
|
||||
{
|
||||
if (m_SpriteRenderer != null)
|
||||
{
|
||||
m_SpriteRenderer.enabled = true;
|
||||
}
|
||||
if (m_Trail != null)
|
||||
{
|
||||
m_Trail.SetActive(true);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件相关
|
||||
public void InitEvent()
|
||||
{
|
||||
//FishingPinballAct.Subscribe<EventPinballResumePelletData>(ResumePellet);
|
||||
//FishingPinballAct.Subscribe<EventPinballLaunchPelletData>(OnLaunchPelletDataEvent);
|
||||
}
|
||||
|
||||
//public void OnLaunchPelletDataEvent(EventPinballLaunchPelletData data)
|
||||
//{
|
||||
// if (data == null) return;
|
||||
// LaunchPellet(data.Force);
|
||||
//}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
private Vector3 m_OriginalPosition;
|
||||
private Quaternion m_OriginalQuaternion;
|
||||
// Start is called before the first frame update
|
||||
public void InitPellet(int recordTimes)
|
||||
{
|
||||
m_OriginalPosition = transform.position;
|
||||
m_OriginalQuaternion = transform.rotation;
|
||||
|
||||
m_ReadyToLaunch = false;
|
||||
|
||||
InitEvent();
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
ClearPelletTrackInfo(recordTimes);
|
||||
CreatePelletTrackInfoCsv(EventPinballConfig.CSVFileName);
|
||||
//#endif
|
||||
|
||||
SetState(EventPinballState.Prepare);
|
||||
|
||||
ResetPellet();
|
||||
|
||||
//GetDataManager().InitGameRound();
|
||||
|
||||
//m_Text.text = GContext.container.Resolve<EventPinballDataManager>().GetSaveFilepath(EventPinballConfig.CSVFileName);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
//#if UNITY_EDITOR
|
||||
if (m_State == EventPinballState.Running)
|
||||
{
|
||||
if (m_Rigidbody2D.IsSleeping())
|
||||
{
|
||||
m_CumulativeTime += Time.deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CumulativeTime = 0;
|
||||
}
|
||||
|
||||
if (m_CumulativeTime > 0.1f)
|
||||
{
|
||||
GetDataManager().ReturnConsumedToken();
|
||||
ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_104"));
|
||||
|
||||
HideRenderer();
|
||||
//StaticBall();
|
||||
|
||||
SetState(EventPinballState.Ended);
|
||||
FishingPinballAct.Publish(new EventPinballResumePelletData());
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (m_ReadyToLaunch)
|
||||
{
|
||||
m_Rigidbody2D.bodyType = RigidbodyType2D.Dynamic;
|
||||
m_Rigidbody2D.isKinematic = false;
|
||||
|
||||
var dir = new Vector2(0f, 1f);
|
||||
m_Rigidbody2D.AddForce(dir * m_Force, ForceMode2D.Impulse);
|
||||
m_ReadyToLaunch = false;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballPellet.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballPellet.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3637ebbbedeaa94ab5626b04ae4ac18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
132
Assets/Scripts/EventPinball/PinballPelletTrackInfo.cs
Normal file
132
Assets/Scripts/EventPinball/PinballPelletTrackInfo.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballPelletTrackInfo
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public float Force { get; set; }
|
||||
public float Gravity { get; set; }
|
||||
public int Score { get; set; }
|
||||
public int Multiple { get; set; }
|
||||
public List<PinballPelletTrackNode> TrackNodeList = new List<PinballPelletTrackNode>();
|
||||
public List<string> RoutePointList = new List<string>();
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder str = new StringBuilder("");
|
||||
str.Append(ID + ",");
|
||||
str.Append(Name + ",");
|
||||
str.Append(Force + ",");
|
||||
|
||||
int count = RoutePointList.Count;
|
||||
str.Append(count + ",");
|
||||
str.Append(Multiple + ",");
|
||||
str.Append(Score + ",");
|
||||
|
||||
//if (count > 0)
|
||||
//{
|
||||
// str.Append(RoutePointList[0]);
|
||||
//}
|
||||
//for (int i = 1; i < count; ++i)
|
||||
//{
|
||||
// str.Append("_" + RoutePointList[i]);
|
||||
//}
|
||||
//str.Append(",");
|
||||
|
||||
////str.Append("total_" + count);
|
||||
|
||||
//if (count > 0)
|
||||
//{
|
||||
// Dictionary<string, int> temp = new Dictionary<string, int>();
|
||||
// foreach (var item in RoutePointList)
|
||||
// {
|
||||
// if (temp.ContainsKey(item))
|
||||
// {
|
||||
// int value = temp[item];
|
||||
// value++;
|
||||
// temp[item] = value;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// temp.Add(item, 1);
|
||||
// }
|
||||
// }
|
||||
// foreach (var item in temp)
|
||||
// {
|
||||
// str.Append("-" + item.Key + "_" + item.Value);
|
||||
// }
|
||||
//}
|
||||
|
||||
//str.Append(",");
|
||||
|
||||
//foreach (var item in TrackNodeList)
|
||||
//{
|
||||
// str.Append(item.ToString());
|
||||
//}
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var item in TrackNodeList)
|
||||
{
|
||||
item.Clear();
|
||||
}
|
||||
TrackNodeList.Clear();
|
||||
RoutePointList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public class PinballPelletTrackNode
|
||||
{
|
||||
public EventPinballTrackType TrackType { get; set; }
|
||||
public string ContactName { get; set; }
|
||||
public string MaterialName { get; set; }
|
||||
public List<TrackNodeContactPoint2D> ContactPoint2DList = new List<TrackNodeContactPoint2D>();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
int count = ContactPoint2DList.Count;
|
||||
|
||||
StringBuilder str = new StringBuilder("");
|
||||
str.Append(TrackType + "-");
|
||||
if (count > 0)
|
||||
{
|
||||
str.Append(ContactName + "_" + MaterialName + "-");
|
||||
}
|
||||
else
|
||||
{
|
||||
str.Append(ContactName + "_" + MaterialName + "|");
|
||||
}
|
||||
|
||||
foreach (var item in ContactPoint2DList)
|
||||
{
|
||||
str.Append(item.ToString());
|
||||
}
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
ContactPoint2DList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public class TrackNodeContactPoint2D
|
||||
{
|
||||
public Vector2 Velocity { get; set; }
|
||||
public Vector2 Position { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder str = new StringBuilder("");
|
||||
str.Append("V(" + Velocity.x + "_" + Velocity.y + ")-");
|
||||
str.Append("P(" + Position.x + "_" + Position.y + ")|");
|
||||
return str.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballPelletTrackInfo.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballPelletTrackInfo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e5b954b96638cf49b16bc3d6d42193c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/EventPinball/PinballRendererSortSettings.cs
Normal file
18
Assets/Scripts/EventPinball/PinballRendererSortSettings.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballRendererSortSettings : MonoBehaviour
|
||||
{
|
||||
public int OrderInLayer = 3;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
var renderer = GetComponent<Renderer>();
|
||||
renderer.sortingOrder = OrderInLayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3371b033e934c04c9ae2f36c1d38b04
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
252
Assets/Scripts/EventPinball/PinballSceneController.cs
Normal file
252
Assets/Scripts/EventPinball/PinballSceneController.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
using asap.core;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballSceneController : MonoBehaviour
|
||||
{
|
||||
#region 数据相关
|
||||
private EventPinballDataManager m_DataManager;
|
||||
#endregion
|
||||
|
||||
#region 新手相关
|
||||
[Header("新手相关设置")]
|
||||
[SerializeField] public SpriteRenderer FiringPin;
|
||||
|
||||
private void HideFiringPin(EventPinballHideFiringPinData data)
|
||||
{
|
||||
if (FiringPin != null)
|
||||
{
|
||||
if (FiringPin.gameObject.activeSelf == true)
|
||||
{
|
||||
FiringPin.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowFiringPin(EventPinballShowFiringPinData data)
|
||||
{
|
||||
if (FiringPin != null)
|
||||
{
|
||||
if (FiringPin.gameObject.activeSelf == false)
|
||||
{
|
||||
FiringPin.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 动画相关
|
||||
public Transform IconPinball;
|
||||
[Header("动画相关设置")]
|
||||
[SerializeField] private Animation m_ArrowBreathAnim;
|
||||
[SerializeField] private List<GameObject> m_HideArrowGameObjectList = new List<GameObject>();
|
||||
public void PlayArrowBreathAnim(EventPinballPlayArrowBreathAnimData data)
|
||||
{
|
||||
m_ArrowBreathAnim.Play();
|
||||
}
|
||||
public void HideArrowGameObjectList(EventPinballStopArrowBreathAnimData data)
|
||||
{
|
||||
m_ArrowBreathAnim.Stop();
|
||||
foreach (var item in m_HideArrowGameObjectList)
|
||||
{
|
||||
item.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private string m_LightOnAnimName;
|
||||
[SerializeField] private float m_LightOnAnimTime;
|
||||
[SerializeField] private Animator m_LightOnAnim;
|
||||
public void PlayLightOnAnim(EventPinballPlayLightOnAnimData data)
|
||||
{
|
||||
m_LightOnAnim.gameObject.SetActive(true);
|
||||
m_LightOnAnim.Play(m_LightOnAnimName);
|
||||
this.StartCoroutine(StopLightOnAnim());
|
||||
}
|
||||
private IEnumerator StopLightOnAnim()
|
||||
{
|
||||
yield return new WaitForSeconds(m_LightOnAnimTime);
|
||||
m_LightOnAnim.gameObject.SetActive(false);
|
||||
//FishingPinballAct.Publish(new EventPinballRewardUpdateData()
|
||||
//{
|
||||
// Scores = m_DataManager.TemporaryScore
|
||||
//});
|
||||
//FishingPinballAct.Publish<EventPinballStopLightOnAnimData>(new EventPinballStopLightOnAnimData());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 能量箭头相关
|
||||
[SerializeField] private List<SpriteRenderer> m_EnergyArrowList = new List<SpriteRenderer>();
|
||||
[SerializeField] private Color m_EnergyArrowColorBright = Color.white;
|
||||
[SerializeField] private Color m_EnergyArrowColorDark = Color.black;
|
||||
private float m_RestoreIntervalTime = 0.1f;
|
||||
public void UpdateEnergyArrowList(EventPinballEnergyArrowData data)
|
||||
{
|
||||
if (data == null) return;
|
||||
|
||||
int count = m_EnergyArrowList.Count;
|
||||
float step = 1.0f / count;
|
||||
int index = (int)Mathf.Ceil(data.Energy / step);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
SpriteRenderer spriteRenderer = m_EnergyArrowList[i];
|
||||
if (i < index)
|
||||
{
|
||||
spriteRenderer.color = m_EnergyArrowColorBright;
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteRenderer.color = m_EnergyArrowColorDark;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void RestoreEnergyArrowList(EventPinballEnergyArrowRestoreData data)
|
||||
{
|
||||
if (data == null) return;
|
||||
this.StartCoroutine(RestoreEnergyArrowListToDark());
|
||||
}
|
||||
public IEnumerator RestoreEnergyArrowListToDark()
|
||||
{
|
||||
int count = m_EnergyArrowList.Count;
|
||||
int brightIndex = -1;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
SpriteRenderer spriteRenderer = m_EnergyArrowList[i];
|
||||
if (spriteRenderer.color == m_EnergyArrowColorBright)
|
||||
{
|
||||
brightIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (brightIndex >= 0)
|
||||
{
|
||||
for (int i = brightIndex; i >= 0; i--)
|
||||
{
|
||||
yield return new WaitForSeconds(m_RestoreIntervalTime);
|
||||
SpriteRenderer spriteRenderer = m_EnergyArrowList[i];
|
||||
spriteRenderer.color = m_EnergyArrowColorDark;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 圆形进度相关
|
||||
[Header("奖励圆盘特效&动画相关设置")]
|
||||
[SerializeField] private int m_ResponseNumber = 10; // 相应次数
|
||||
public List<PinballCircularProgress> m_CircularProgressList = new List<PinballCircularProgress>();
|
||||
public void UpdateBonusCircularProgress(EventPinballUpdateBonusCircularProgress data)
|
||||
{
|
||||
if (m_DataManager == null) return;
|
||||
|
||||
float progress = m_DataManager.GetBonusResponseRatio();
|
||||
foreach (var item in m_CircularProgressList)
|
||||
{
|
||||
item.SetProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Transform> m_CircularAnimList = new List<Transform>();
|
||||
public float m_CircularAnimRotationalSpeed = -180f;
|
||||
public void UpdateCircularRotationalAnim()
|
||||
{
|
||||
if (m_CircularAnimList.Count > 0)
|
||||
{
|
||||
var firstItem = m_CircularAnimList[0];
|
||||
|
||||
Vector3 eulerAngles = firstItem.eulerAngles;
|
||||
|
||||
eulerAngles += new Vector3(0f, 0f, 1f) * m_CircularAnimRotationalSpeed * Time.deltaTime;
|
||||
|
||||
if (eulerAngles.z > 360f)
|
||||
{
|
||||
eulerAngles.z -= 360f;
|
||||
}
|
||||
else if (eulerAngles.z < -360f)
|
||||
{
|
||||
eulerAngles.z += 360f;
|
||||
}
|
||||
|
||||
foreach (var item in m_CircularAnimList)
|
||||
{
|
||||
item.eulerAngles = eulerAngles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_IsShowCircularRotationalAnim = false;
|
||||
public void ShowCircularRotationalAnim(EventPinballShowCircularRotationalAnim data)
|
||||
{
|
||||
foreach (var item in m_CircularProgressList)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
foreach (var item in m_CircularAnimList)
|
||||
{
|
||||
item.gameObject.SetActive(true);
|
||||
item.eulerAngles = Vector3.zero;
|
||||
}
|
||||
m_IsShowCircularRotationalAnim = true;
|
||||
}
|
||||
public void HideCircularRotationalAnim(EventPinballHideCircularRotationalAnim data)
|
||||
{
|
||||
m_IsShowCircularRotationalAnim = false;
|
||||
|
||||
foreach (var item in m_CircularProgressList)
|
||||
{
|
||||
item.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
foreach (var item in m_CircularAnimList)
|
||||
{
|
||||
item.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件
|
||||
public void InitEvent()
|
||||
{
|
||||
FishingPinballAct.Subscribe<EventPinballEnergyArrowData>(UpdateEnergyArrowList);
|
||||
FishingPinballAct.Subscribe<EventPinballEnergyArrowRestoreData>(RestoreEnergyArrowList);
|
||||
FishingPinballAct.Subscribe<EventPinballUpdateBonusCircularProgress>(UpdateBonusCircularProgress);
|
||||
FishingPinballAct.Subscribe<EventPinballPlayArrowBreathAnimData>(PlayArrowBreathAnim);
|
||||
FishingPinballAct.Subscribe<EventPinballStopArrowBreathAnimData>(HideArrowGameObjectList);
|
||||
FishingPinballAct.Subscribe<EventPinballPlayLightOnAnimData>(PlayLightOnAnim);
|
||||
FishingPinballAct.Subscribe<EventPinballShowFiringPinData>(ShowFiringPin);
|
||||
FishingPinballAct.Subscribe<EventPinballHideFiringPinData>(HideFiringPin);
|
||||
FishingPinballAct.Subscribe<EventPinballShowCircularRotationalAnim>(ShowCircularRotationalAnim);
|
||||
FishingPinballAct.Subscribe<EventPinballHideCircularRotationalAnim>(HideCircularRotationalAnim);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
m_DataManager = GContext.container.Resolve<EventPinballDataManager>();
|
||||
m_DataManager.BonusResponseNumber = m_ResponseNumber;
|
||||
|
||||
InitEvent();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (Input.GetKeyUp(KeyCode.Escape))
|
||||
{
|
||||
// 关闭当前Act
|
||||
GContext.Publish(new UnloadActToNextAct());
|
||||
}
|
||||
|
||||
if (m_IsShowCircularRotationalAnim)
|
||||
{
|
||||
UpdateCircularRotationalAnim();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballSceneController.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballSceneController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74d285fcdf9ab914cbe0d5af5ce05a34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
36
Assets/Scripts/EventPinball/PinballScoringWidgetBase.cs
Normal file
36
Assets/Scripts/EventPinball/PinballScoringWidgetBase.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballScoringWidgetBase : MonoBehaviour
|
||||
{
|
||||
#region 数据
|
||||
public int Number = 5; // 分数
|
||||
public Rigidbody2D Rigidbody2D; // 2D刚体
|
||||
public PhysicsMaterial2D ValidMaterial; // 有效材质
|
||||
public PhysicsMaterial2D InvalidMaterial; // 无效材质
|
||||
protected EventPinballBonusType m_BonusType = EventPinballBonusType.TypeScore;
|
||||
public EventPinballBonusType BonusType { get => m_BonusType; }
|
||||
public virtual string GetTip()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public void ResetValidMaterial()
|
||||
{
|
||||
if (Rigidbody2D != null && ValidMaterial != null)
|
||||
{
|
||||
Rigidbody2D.sharedMaterial = ValidMaterial;
|
||||
}
|
||||
}
|
||||
public void SetInvalidMaterial()
|
||||
{
|
||||
if (Rigidbody2D != null && InvalidMaterial != null)
|
||||
{
|
||||
Rigidbody2D.sharedMaterial = InvalidMaterial;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballScoringWidgetBase.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballScoringWidgetBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 209889935e9999f43939f9be5591e9e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
73
Assets/Scripts/EventPinball/PinballScoringWidgetMultiple.cs
Normal file
73
Assets/Scripts/EventPinball/PinballScoringWidgetMultiple.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using asap.core;
|
||||
using Game;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballScoringWidgetMultiple : PinballScoringWidgetBase
|
||||
{
|
||||
#region 声音相关
|
||||
[Header("声音设置")]
|
||||
[SerializeField] private AssetReferenceT<AudioClip> m_Sound;
|
||||
public void PlaySound()
|
||||
{
|
||||
GContext.Publish(new AssetReferenceAudioClip(m_Sound, time: 0f));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 特效相关
|
||||
[Header("特效设置")]
|
||||
[SerializeField] public GameObject m_Effect;
|
||||
[SerializeField] public float m_EffectDuration = 0.6f;
|
||||
|
||||
public void ShowEffect()
|
||||
{
|
||||
if (m_Effect != null)
|
||||
{
|
||||
if (m_Effect.activeSelf == false)
|
||||
{
|
||||
m_Effect.SetActive(true);
|
||||
}
|
||||
StartCoroutine(AutoHideEffect());
|
||||
}
|
||||
}
|
||||
private IEnumerator AutoHideEffect()
|
||||
{
|
||||
yield return new WaitForSeconds(m_EffectDuration);
|
||||
HideEffect(null);
|
||||
}
|
||||
public void HideEffect(EventPinballHideWidgetMultipleEffectData data)
|
||||
{
|
||||
if (m_Effect != null)
|
||||
{
|
||||
if (m_Effect.activeSelf == true)
|
||||
{
|
||||
m_Effect.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 数据
|
||||
public override string GetTip()
|
||||
{
|
||||
return "x" + Number;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
m_BonusType = EventPinballBonusType.TypeMultiple;
|
||||
|
||||
HideEffect(null);
|
||||
|
||||
FishingPinballAct.Subscribe<EventPinballHideWidgetMultipleEffectData>(HideEffect);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 762a90a003e57774c96d02202561b4cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
144
Assets/Scripts/EventPinball/PinballScoringWidgetScore.cs
Normal file
144
Assets/Scripts/EventPinball/PinballScoringWidgetScore.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballScoringWidgetScore : PinballScoringWidgetBase
|
||||
{
|
||||
[SerializeField] private TextMeshPro m_TextMesh;
|
||||
|
||||
#region 特效相关
|
||||
[Header("特效设置")]
|
||||
[SerializeField] public GameObject m_Effect1;
|
||||
[SerializeField] public GameObject m_Effect2;
|
||||
[SerializeField] public float m_Effect1Duration = 0.3f;
|
||||
[SerializeField] public float m_Effect2Duration = 0.3f;
|
||||
|
||||
private float m_Effect1_CumulativeTime = 0f;
|
||||
public void ShowEffect1()
|
||||
{
|
||||
m_Effect1_CumulativeTime = 0f;
|
||||
}
|
||||
private void UpdateEffect1()
|
||||
{
|
||||
if (m_Effect1 != null)
|
||||
{
|
||||
if (m_Effect1_CumulativeTime < m_Effect1Duration)
|
||||
{
|
||||
if (m_Effect1.activeSelf == false)
|
||||
{
|
||||
m_Effect1.SetActive(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Effect1.activeSelf == true)
|
||||
{
|
||||
m_Effect1.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
m_Effect1_CumulativeTime += Time.deltaTime;
|
||||
if (m_Effect1_CumulativeTime > float.MaxValue)
|
||||
{
|
||||
m_Effect1_CumulativeTime = m_Effect1Duration + 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float m_Effect2_CumulativeTime = 0f;
|
||||
public void ShowEffect2(EventPinballShowWidgetScoreEffect2Data data)
|
||||
{
|
||||
m_Effect2_CumulativeTime = 0f;
|
||||
}
|
||||
private void UpdateEffect2()
|
||||
{
|
||||
if (m_Effect2 != null)
|
||||
{
|
||||
if (m_Effect2_CumulativeTime < m_Effect2Duration)
|
||||
{
|
||||
if (m_Effect2.activeSelf == false)
|
||||
{
|
||||
m_Effect2.SetActive(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Effect2.activeSelf == true)
|
||||
{
|
||||
m_Effect2.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
m_Effect2_CumulativeTime += Time.deltaTime;
|
||||
if (m_Effect2_CumulativeTime > float.MaxValue)
|
||||
{
|
||||
m_Effect2_CumulativeTime = m_Effect2Duration + 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 数据
|
||||
public override string GetTip()
|
||||
{
|
||||
return "+" + Number;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件相关
|
||||
private void InitEvent()
|
||||
{
|
||||
FishingPinballAct.Subscribe<EventPinballBasicScore>(UpdateScore);
|
||||
FishingPinballAct.Subscribe<EventPinballBasicScoreHideData>(HideScore);
|
||||
FishingPinballAct.Subscribe<EventPinballBasicScoreShowData>(ShowScore);
|
||||
FishingPinballAct.Subscribe<EventPinballShowWidgetScoreEffect2Data>(ShowEffect2);
|
||||
}
|
||||
private void UpdateScore(EventPinballBasicScore data)
|
||||
{
|
||||
if (data == null) return;
|
||||
Number = data.Score;
|
||||
|
||||
if (m_TextMesh != null)
|
||||
{
|
||||
m_TextMesh.text = "" + Number;
|
||||
}
|
||||
}
|
||||
private void HideScore(EventPinballBasicScoreHideData data)
|
||||
{
|
||||
if (m_TextMesh != null)
|
||||
{
|
||||
m_TextMesh.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
private void ShowScore(EventPinballBasicScoreShowData data)
|
||||
{
|
||||
if (m_TextMesh != null)
|
||||
{
|
||||
m_TextMesh.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
m_BonusType = EventPinballBonusType.TypeScore;
|
||||
InitEvent();
|
||||
|
||||
m_Effect1_CumulativeTime = m_Effect1Duration + 1f;
|
||||
m_Effect2_CumulativeTime = m_Effect2Duration + 1f;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
UpdateEffect1();
|
||||
UpdateEffect2();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12c87ee671752054eba9a85d63c2ccb1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
50
Assets/Scripts/EventPinball/PinballSpring.cs
Normal file
50
Assets/Scripts/EventPinball/PinballSpring.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballSpring : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Transform m_BottomPosition;
|
||||
[SerializeField] private SpriteRenderer m_SpriteRenderer;
|
||||
[SerializeField] private float m_MaxRatio = 0.5f;
|
||||
|
||||
#region 事件相关
|
||||
public void InitEvent()
|
||||
{
|
||||
FishingPinballAct.Subscribe<EventPinballSpringUpdateData>(UpdateSpring);
|
||||
}
|
||||
public void UpdateSpring(EventPinballSpringUpdateData data)
|
||||
{
|
||||
var spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
|
||||
float boundX = spriteRenderer.bounds.size.x;
|
||||
|
||||
float reservedRatio = 1.0f - m_MaxRatio;
|
||||
float validRatio = m_MaxRatio * data.Ratio;
|
||||
float scaleY = reservedRatio + validRatio;
|
||||
|
||||
m_SpriteRenderer.transform.localScale = new Vector3(m_SpriteRenderer.transform.localScale.x, scaleY, m_SpriteRenderer.transform.localScale.z);
|
||||
|
||||
float height = m_SpriteRenderer.bounds.size.y;
|
||||
|
||||
float y = m_BottomPosition.position.y + height / 2;
|
||||
transform.position = new Vector3(transform.position.x, y, transform.position.z);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
InitEvent();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballSpring.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballSpring.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ef39d92bc3420647b49d3cf46a4e0bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
67
Assets/Scripts/EventPinball/PinballSwitcher.cs
Normal file
67
Assets/Scripts/EventPinball/PinballSwitcher.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class PinballSwitcher : MonoBehaviour
|
||||
{
|
||||
public Animator m_Animator;
|
||||
public string m_OpenAnimation;
|
||||
public string m_CloseAnimation;
|
||||
public GameObject m_Collider;
|
||||
|
||||
#region 状态相关
|
||||
private EventPinballSwitcherState m_State;
|
||||
public bool IsOpen()
|
||||
{
|
||||
return m_State == EventPinballSwitcherState.Open;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 动画相关
|
||||
public void OpenSwitcher(EventPinballSwitcherOpen data)
|
||||
{
|
||||
if (m_Animator != null && !string.IsNullOrEmpty(m_OpenAnimation))
|
||||
{
|
||||
m_Animator.Play(m_OpenAnimation);
|
||||
m_State = EventPinballSwitcherState.Open;
|
||||
}
|
||||
if (m_Collider != null)
|
||||
{
|
||||
m_Collider.SetActive(false);
|
||||
}
|
||||
}
|
||||
public void CloseSwitcher(EventPinballSwitcherClose data)
|
||||
{
|
||||
if (m_Animator != null && !string.IsNullOrEmpty(m_CloseAnimation))
|
||||
{
|
||||
m_Animator.Play(m_CloseAnimation);
|
||||
m_State = EventPinballSwitcherState.Close;
|
||||
}
|
||||
if (m_Collider != null)
|
||||
{
|
||||
m_Collider.SetActive(true);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件相关
|
||||
public void InitEvent()
|
||||
{
|
||||
FishingPinballAct.Subscribe<EventPinballSwitcherOpen>(OpenSwitcher);
|
||||
FishingPinballAct.Subscribe<EventPinballSwitcherClose>(CloseSwitcher);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
InitEvent();
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballSwitcherOpen());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballSwitcher.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballSwitcher.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8f250885ca25fa44b8952e0988ea983
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
59
Assets/Scripts/EventPinball/PinballSwitcherCloseDetection.cs
Normal file
59
Assets/Scripts/EventPinball/PinballSwitcherCloseDetection.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
[RequireComponent(typeof(Collider2D))]
|
||||
public class PinballSwitcherCloseDetection : MonoBehaviour
|
||||
{
|
||||
public PinballPellet m_Pellet;
|
||||
public PinballSwitcher m_Switcher;
|
||||
public int m_WaitFrames = 3;
|
||||
|
||||
#region Switcher
|
||||
public IEnumerator CloseSwitcher()
|
||||
{
|
||||
int index = 0;
|
||||
while (index < m_WaitFrames)
|
||||
{
|
||||
yield return null;
|
||||
index++;
|
||||
}
|
||||
|
||||
FishingPinballAct.Publish(new EventPinballSwitcherClose());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Collider2D
|
||||
private void OnCollisionExit2D(Collision2D collision)
|
||||
{
|
||||
if (m_Pellet != null && m_Switcher != null && m_Switcher.IsOpen() && collision.gameObject == m_Pellet.gameObject)
|
||||
{
|
||||
StartCoroutine(CloseSwitcher());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 事件相关
|
||||
public void InitEvent()
|
||||
{
|
||||
FishingPinballAct.Subscribe<EventPinballSetDummyPelletData>(SetData);
|
||||
}
|
||||
|
||||
public void SetData(EventPinballSetDummyPelletData data)
|
||||
{
|
||||
if (data == null) return;
|
||||
m_Pellet = data.Pellet;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
private void Awake()
|
||||
{
|
||||
InitEvent();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8efb55e062aa1b847b95e6eae6097c4e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
33
Assets/Scripts/EventPinball/PinballUtils.cs
Normal file
33
Assets/Scripts/EventPinball/PinballUtils.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public static class PinballUtils
|
||||
{
|
||||
public static void ExportToCSV(List<string> list, string filePath)
|
||||
{
|
||||
if (list == null || list.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("数据为空,无法导出 CSV 文件。");
|
||||
return;
|
||||
}
|
||||
|
||||
using (StreamWriter sw = new StreamWriter(filePath, true))
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
sw.WriteLine(item);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"CSV 文件已保存到: {filePath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/PinballUtils.cs.meta
Normal file
11
Assets/Scripts/EventPinball/PinballUtils.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14cdafaf6baebae4bb2d657dd5e65e10
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/EventPinball/Shaders.meta
Normal file
8
Assets/Scripts/EventPinball/Shaders.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c98f51c606786774a8c16d32b227928a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
87
Assets/Scripts/EventPinball/Shaders/CircularProgress.shader
Normal file
87
Assets/Scripts/EventPinball/Shaders/CircularProgress.shader
Normal file
@@ -0,0 +1,87 @@
|
||||
Shader "Bamboo/CircularProgress"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_Progress ("Progress", Range(0, 1)) = 0
|
||||
_Color ("Color", Color) = (1,1,1,1)
|
||||
_BackgroundColor ("Background Color", Color) = (0,0,0,0)
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"Queue"="Transparent"
|
||||
"RenderType"="Transparent"
|
||||
}
|
||||
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
Cull Off
|
||||
ZWrite Off
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
float _Progress;
|
||||
fixed4 _Color;
|
||||
fixed4 _BackgroundColor;
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
// 获取UV坐标相对于中心的位置
|
||||
float2 center = float2(0.5, 0.5);
|
||||
float2 dir = i.uv - center;
|
||||
|
||||
// 计算当前点到圆心的距离
|
||||
float dist = length(dir);
|
||||
|
||||
// 计算当前点的角度(从上方开始顺时针方向)
|
||||
// atan2返回[-π, π],我们转换为[0, 1]范围
|
||||
float angle = atan2(dir.x, dir.y) / (2.0 * 3.14159265359);
|
||||
angle = angle < 0 ? angle + 1.0 : angle;
|
||||
|
||||
// 采样纹理
|
||||
fixed4 col = tex2D(_MainTex, i.uv);
|
||||
|
||||
// 根据进度决定是否显示
|
||||
float visible = (dist <= 0.5) && (angle <= _Progress);
|
||||
|
||||
// 混合颜色
|
||||
col.rgb = col.rgb * _Color.rgb;
|
||||
col.a = col.a * _Color.a * visible;
|
||||
|
||||
// 如果不可见,使用背景色
|
||||
return lerp(_BackgroundColor, col, visible);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1423250c4744a04596fc60f2ce062b6
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/EventPinball/tips.meta
Normal file
8
Assets/Scripts/EventPinball/tips.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80bba6e2f0550644abc6d29a27f6c9be
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
70
Assets/Scripts/EventPinball/tips/FloatingText.cs
Normal file
70
Assets/Scripts/EventPinball/tips/FloatingText.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
|
||||
namespace game
|
||||
{
|
||||
[RequireComponent(typeof(TextMeshPro))]
|
||||
public class FloatingText : MonoBehaviour
|
||||
{
|
||||
[Header("Type")]
|
||||
public EventPinballBonusType FloatingTextType;
|
||||
|
||||
[Header("Movement Settings")]
|
||||
public float moveSpeed = 1f;
|
||||
public float fadeDuration = 1f;
|
||||
|
||||
[Header("Renderer")]
|
||||
public int OrderInLayer = 3;
|
||||
|
||||
private TextMeshPro textMesh;
|
||||
private float currentAlpha = 1f;
|
||||
private float timer = 0f;
|
||||
private Vector3 moveDirection = Vector3.up;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
textMesh = GetComponent<TextMeshPro>();
|
||||
|
||||
var renderer = GetComponent<Renderer>();
|
||||
renderer.sortingOrder = OrderInLayer;
|
||||
}
|
||||
|
||||
public void Initialize(string text, Vector3 position)
|
||||
{
|
||||
transform.position = position;
|
||||
textMesh.text = text;
|
||||
|
||||
currentAlpha = 1f;
|
||||
timer = 0f;
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// 移动
|
||||
transform.position += moveDirection * moveSpeed * Time.deltaTime;
|
||||
|
||||
// 淡出
|
||||
timer += Time.deltaTime;
|
||||
if (timer >= fadeDuration)
|
||||
{
|
||||
if (FloatingTextType == EventPinballBonusType.TypeScore)
|
||||
{
|
||||
FloatingTextPool.Instance.ReturnToScorePool(this);
|
||||
}
|
||||
else if (FloatingTextType == EventPinballBonusType.TypeMultiple)
|
||||
{
|
||||
FloatingTextPool.Instance.ReturnToMultiplePool(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
currentAlpha = Mathf.Lerp(1f, 0f, timer / fadeDuration);
|
||||
var color = textMesh.color;
|
||||
color.a = currentAlpha;
|
||||
textMesh.color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/tips/FloatingText.cs.meta
Normal file
11
Assets/Scripts/EventPinball/tips/FloatingText.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fce2a3c44f5cc2d4ead5a2ced75e2732
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
106
Assets/Scripts/EventPinball/tips/FloatingTextPool.cs
Normal file
106
Assets/Scripts/EventPinball/tips/FloatingTextPool.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace game
|
||||
{
|
||||
public class FloatingTextPool : MonoBehaviour
|
||||
{
|
||||
public static FloatingTextPool Instance { get; private set; }
|
||||
|
||||
[SerializeField] private GameObject floatingScoreTextPrefab;
|
||||
[SerializeField] private GameObject floatingMultipleTextPrefab;
|
||||
[SerializeField] private int initialScorePoolSize = 12;
|
||||
[SerializeField] private int initialMultiplePoolSize = 2;
|
||||
|
||||
private Queue<FloatingText> m_ScorePool = new Queue<FloatingText>();
|
||||
private Queue<FloatingText> m_MultiplePool = new Queue<FloatingText>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
InitializePool();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
m_ScorePool.Clear();
|
||||
m_ScorePool = null;
|
||||
|
||||
m_MultiplePool.Clear();
|
||||
m_MultiplePool = null;
|
||||
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
private void InitializePool()
|
||||
{
|
||||
for (int i = 0; i < initialScorePoolSize; i++)
|
||||
{
|
||||
CreateNewScoreTextObject();
|
||||
}
|
||||
|
||||
for (int i = 0; i < initialMultiplePoolSize; i++)
|
||||
{
|
||||
CreateNewMultipleTextObject();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateNewScoreTextObject()
|
||||
{
|
||||
var obj = Instantiate(floatingScoreTextPrefab, transform);
|
||||
var floatingText = obj.GetComponent<FloatingText>();
|
||||
floatingText.gameObject.SetActive(false);
|
||||
m_ScorePool.Enqueue(floatingText);
|
||||
}
|
||||
|
||||
private void CreateNewMultipleTextObject()
|
||||
{
|
||||
var obj = Instantiate(floatingMultipleTextPrefab, transform);
|
||||
var floatingText = obj.GetComponent<FloatingText>();
|
||||
floatingText.gameObject.SetActive(false);
|
||||
m_MultiplePool.Enqueue(floatingText);
|
||||
}
|
||||
|
||||
public FloatingText GetFloatingScoreText()
|
||||
{
|
||||
if (m_ScorePool.Count == 0)
|
||||
{
|
||||
CreateNewScoreTextObject();
|
||||
}
|
||||
|
||||
var text = m_ScorePool.Dequeue();
|
||||
text.gameObject.SetActive(true);
|
||||
return text;
|
||||
}
|
||||
|
||||
public FloatingText GetFloatingMultipleText()
|
||||
{
|
||||
if (m_ScorePool.Count == 0)
|
||||
{
|
||||
CreateNewMultipleTextObject();
|
||||
}
|
||||
|
||||
var text = m_MultiplePool.Dequeue();
|
||||
text.gameObject.SetActive(true);
|
||||
return text;
|
||||
}
|
||||
|
||||
public void ReturnToScorePool(FloatingText text)
|
||||
{
|
||||
text.gameObject.SetActive(false);
|
||||
m_ScorePool.Enqueue(text);
|
||||
}
|
||||
public void ReturnToMultiplePool(FloatingText text)
|
||||
{
|
||||
text.gameObject.SetActive(false);
|
||||
m_MultiplePool.Enqueue(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EventPinball/tips/FloatingTextPool.cs.meta
Normal file
11
Assets/Scripts/EventPinball/tips/FloatingTextPool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 333a4cb1ba0446646b7439ef7923e586
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user