MayHeCome/Assets/Scripts/BlobController.cs

218 lines
6.6 KiB
C#
Raw Normal View History

2024-12-18 09:55:34 +00:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;
using Random = UnityEngine.Random;
public class BlobController : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerMoveHandler, IPointerEnterHandler, IPointerExitHandler
{
private float efficiency = 1f;
public float buffMultiplier = 1f;
public float buffAdder= 1f;
public float Efficiency => efficiency * buffMultiplier + buffAdder;
public List<BuffElement> BlobBuffs = new();
public int blobID = 0;
public bool specialBlob = false;
private Buildings belongingBuilding = null;
public Buildings BelongingBuilding
{
get => belongingBuilding;
set
{
belongingBuilding = value;
if (belongingBuilding)
{
moveCancellation.Cancel();
}
}
}
public Animator animator;
public Vector3 dragOffset = Vector3.zero;
public float BlobWonderingSpeed = 1f;
public SceneTransitionManager SceneTransitionManager;
public CancellationTokenSource moveCancellation = new CancellationTokenSource();
public bool isDragging = false;
private bool isBusy = false;
public SpriteRenderer sprite;
private BoxCollider boxCollider;
private Vector3 boxOriginalSize;
public float yBeforeLanding;
public float currentZ;
private float curZOffset = -0.4f;
private float yOffsetTransit = 0.58f;
private int indexPre = 0;
//z坐标-9.1f + SceneIndex * 3.9f -0.4f
//y坐标0.39 + 0.58 * SceneIndex
private void Start()
{
boxCollider = GetComponent<BoxCollider>();
boxOriginalSize = boxCollider.size;
SceneTransitionManager = FindObjectOfType<SceneTransitionManager>();
sprite = GetComponent<SpriteRenderer>();
animator = GetComponent<Animator>();
blobID = BlobManager.Instance.Register(this);
if (SceneTransitionManager)
{
SceneTransitionManager.OnTransition.AddListener(OnTransit);
}
if (specialBlob)
{
animator.Play("Special");
}
}
//-10.3 -5.2 -1.3
//5.1,3.9
public void OnTransit(int SceneIndex)
{
// print(isDragging);
if (!isDragging) return;
if (SceneIndex == SceneTransitionManager.TransitionPoints.Count - 1)
{
//自动放手
OnPointerUp(null);
return;
}
//currentZ = SceneTransitionManager.TransitionPoints[SceneIndex].position.z + 2f;
currentZ = -9.1f + SceneIndex * 3.9f + curZOffset;
transform.position = new Vector3(transform.position.x, transform.position.y, currentZ);
// sprite.sortingOrder = (4 - SceneIndex) * 10 + 5;
}
private void OnDestroy()
{
moveCancellation.Cancel();
BlobManager.Instance.UnRegister(this);
}
private void Update()
{
BlobBuffs.ForEach(b=> b.OnUpdatingEffect(this));
if (isDragging) return;
if (isBusy) return;
if (!BelongingBuilding&&!specialBlob)
{
moveCancellation = new CancellationTokenSource();
_ = Wondering(moveCancellation.Token);
}
}
public async UniTaskVoid AddTimeBuff(BuffElement buff, float second)
{
BlobBuffs.Add(buff);
buff.OnStaringEffect(this);
await UniTask.WaitForSeconds(second);
BlobBuffs.Remove(buff);
buff.OnEndingEffect(this);
}
public void AddBuff(BuffElement buff)
{
BlobBuffs.Add(buff);
buff.OnStaringEffect(this);
}
public async UniTaskVoid Wondering(CancellationToken cancellationToken)
{
isBusy = true;
await UniTask.Delay(1000, cancellationToken:cancellationToken);
animator.SetBool("isWalking", true);
var targetOffset = Random.Range(-1f, 1f);
GetComponent<SpriteRenderer>().flipX = targetOffset < 0;
await transform.DOMoveX( transform.position.x + targetOffset, Mathf.Abs(targetOffset)/ BlobWonderingSpeed).SetEase(Ease.Linear).WithCancellation(cancellationToken);
animator.SetBool("isWalking", false);
isBusy = false;
}
public async UniTaskVoid Landing(CancellationToken cancellationToken)
{
if (Mathf.Abs(transform.position.y - yBeforeLanding) < 0.01)
{
return;
}
isBusy = true;
animator.SetBool("isFalling", true);
//本来该是逻辑方面的东西,但发现执行顺序这个好像反而在前面吗
yBeforeLanding += (SceneTransitionManager.CurrentTrackingPointIndex - indexPre) * yOffsetTransit;
await transform.DOLocalMoveY(yBeforeLanding, Mathf.Sqrt(2* transform.localPosition.y/9.8f)).SetEase(Ease.Linear);
animator.SetBool("isFalling", false);
isBusy = false;
}
#region Pointer行为
public void OnPointerDown(PointerEventData eventData)
{
if (BelongingBuilding) return;
isDragging = true;
isBusy = false;
dragOffset = transform.position - eventData.pointerCurrentRaycast.worldPosition;
boxCollider.size = new Vector3(1000, 1000, 0.1f);
yBeforeLanding = transform.position.y;
moveCancellation.Cancel();
currentZ = transform.position.z;
indexPre = SceneTransitionManager.Instance.CurrentTrackingPointIndex;
}
public void OnPointerUp(PointerEventData eventData)
{
if (BelongingBuilding) return;
isDragging = false;
isBusy = true;
boxCollider.size = boxOriginalSize;
_ = Landing(moveCancellation.Token);
}
public void OnPointerMove(PointerEventData eventData)
{
if (BelongingBuilding) return;
if (!isDragging) return;
// var currentLayer = SceneTransitionManager?.TransitionPoints[SceneTransitionManager.CurrentTrackingPointIndex] ?? transform;
// var currentLayer = transform;
// var currentLayerZ = transform.position.z;
transform.position = eventData.pointerCurrentRaycast.worldPosition + dragOffset;
transform.position = new Vector3(transform.position.x, transform.position.y, currentZ);
}
public void OnPointerEnter(PointerEventData eventData)
{
if (BelongingBuilding) return;
transform.localScale *= 1.2f;
}
public void OnPointerExit(PointerEventData eventData)
{
if (BelongingBuilding) return;
transform.localScale /= 1.2f;
}
#endregion
}