Files
2026-05-26 16:15:54 +08:00

429 lines
13 KiB
C#

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
}
}