MayHeCome/Assets/Scripts/BlobController.cs
2024-12-18 17:55:34 +08:00

218 lines
6.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}