218 lines
6.6 KiB
C#
218 lines
6.6 KiB
C#
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
|
||
|
||
|
||
}
|