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

246 lines
6.1 KiB
C#
Raw Permalink 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.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Castle.Core.Internal;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Serialization;
/// <summary>
/// 挂在脚本,方便额外的处理
/// </summary>
public enum CBoxState
{
Locked = 0,
UnLocking = 1, // 解锁中
UnLocked = 2, // 已解锁
Attacking = 3, // 袭击中
Broken = 4 // 破碎
}
public class ChallengeBox : MonoBehaviour
{
[Header("Timeline配置")]
public PlayableDirector AppearTimeline;//出现表现timeline
public PlayableDirector BreakTimeline;//销毁表现timeline
[Header("头像运动参数")]
public float AppearJumpDelay = 4f;//播放出现表现timeline同时延迟多久播放头像动画
[Header("被破坏的箱子")]
private ChallengeBox box;
[Header("箱子破碎,被鳄鱼袭击特效")]
[SerializeField]
private ParticleSystem psBoxBroken;
// 断开藤曼,同时播放吗
[Header("断开藤曼")]
[SerializeField]
private Animation aniKnife;
[SerializeField]
private ParticleSystem psKnife;
// 藤曼退开,可以跳跃
[Header("藤曼退开,箱子可供站立")]
[SerializeField]
private Animation aniBoxOn;
private float _speed = 1.0f;
private void Awake()
{
if (psBoxBroken)
{
psBoxBroken.Stop();
}
if (psKnife)
{
psKnife.Stop();
}
if (aniBoxOn)
{
aniBoxOn.Stop();
}
if (aniKnife)
{
aniKnife.Stop();
// aniKnife.gameObject.SetActive(false);
}
// if (challengeKiller)
// {
// challengeKiller.OnIdle();
// }
}
private void Start()
{
// AppearTimeline.initialTime = 0;
// AppearTimeline.Evaluate();
// // AppearTimeline.playOnAwake();
// IdleTimeline.initialTime = 0;
// IdleTimeline.Evaluate();
// BreakTimeline.initialTime = 0;
// BreakTimeline.Evaluate();
}
private void OnDestroy()
{
}
public void Log(object t)
{
// Debug.Log("");
}
public float GetSpeed()
{
return _speed;
}
public float SpeedUpSeconds(float seconds)
{
return _speed * seconds;
}
public void UpdateTimeController(ChallengeSetAnimationEvent e)
{
_speed = e.speed;
// _timeForUnlocking = e.timeForUnlocking;
// _timeForUnlockingEnd = e.timeForUnLockingEnd;
// _timeForAttackStart = e.timeForAttackStart;
// _timeForAttacking1 = e.timeForAttacking_1;
// _timeForAttacking2 = e.timeForAttacking_2;
// _timeForAttackEnd = e.timeForAttackEnd;
// _timeForAttackEndWait = e.timeForAttackEndWait;
}
public void SnapToEnd(Animation anim, string clipName = null)
{
if (!anim) return;
if (clipName == null)
{
clipName = anim.clip?.name;
}
if (clipName == null)
return;
if (anim[clipName] == null)
{
Log($"动画片段 {clipName} 不存在");
return;
}
// 方法1直接设置时间并采样
anim[clipName].time = anim[clipName].length;
anim.Play(clipName);
anim.Sample();
anim.Stop(clipName);
}
public void SnapToStart(Animation anim)
{
if (!anim || !anim.clip ) return;
var clipName = anim.clip.name;
if (anim[clipName] == null)
{
Log($"动画片段 {clipName} 不存在");
return;
}
// var speed = anim[clipName].speed;
anim.Play(clipName);
anim[clipName].time = 0f;
anim.Sample();
// anim[clipName].speed = 0f;
anim.Stop(clipName);
// anim[clipName].time = speed;
}
//
private async Task OnUnLocking()
{
Log("OnUnlocking");
// aniKnife.gameObject.SetActive(true);
// var knifeName = (from AnimationState state in aniKnife select state.name).FirstOrDefault();
// aniKnife.Play(knifeName);
// // 注意时间是自己调的,有时间最好协助回调中
// await Awaiters.Seconds(SpeedUpSeconds(_timeForUnlocking));
// aniBoxOn.Play();
// await Awaiters.Seconds(SpeedUpSeconds(_timeForUnlockingEnd));
// aniKnife.gameObject.SetActive(true);
AppearTimeline.initialTime = 0;
AppearTimeline.Play();
// AppearTimeline.playableGraph.GetRootPlayable(0).SetSpeed(2.0f);
await Awaiters.Seconds(SpeedUpSeconds(AppearJumpDelay));
}
private async Task OnAttacking()
{
Log("OnAttacking");
BreakTimeline.initialTime = 0;
BreakTimeline?.Play();
}
public void OnLocked()
{
gameObject.SetActive(true);
AppearTimeline.initialTime = 0;
AppearTimeline.Evaluate();
AppearTimeline.Stop();
}
private void OnUnlocked()
{
gameObject.SetActive(true);
AppearTimeline.initialTime = AppearTimeline.duration;
AppearTimeline.Evaluate();
AppearTimeline.Stop();
}
private void OnBroken()
{
Log("OnBroken");
gameObject.SetActive(false);
}
///////
public async Task UpdateState(CBoxState state)
{
Log($"UpdateState({state})");
switch (state)
{
case CBoxState.UnLocked:
OnUnlocked();
break;
case CBoxState.Broken:
OnBroken();
break;
case CBoxState.Locked:
OnLocked();
break;
case CBoxState.UnLocking:
await OnUnLocking();
break;
case CBoxState.Attacking:
await OnAttacking();
break;
default:
throw new ArgumentOutOfRangeException(nameof(state), state, null);
}
}
}