546 lines
24 KiB
C#
546 lines
24 KiB
C#
using UnityEngine;
|
||
using Thousandto.Core.Asset;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
|
||
namespace Thousandto.Cinematic
|
||
{
|
||
//剧情对象管理,流程管理
|
||
public class CinematicObjManager
|
||
{
|
||
private CinematicObj _cObj;
|
||
private FGameObjectVFXBox _vfxbox = new FGameObjectVFXBox();
|
||
|
||
//上一个含有位移事件的关键帧
|
||
private CinematicKeyframe _preTransKeyframe;
|
||
//上一个含有动画世界的关键帧
|
||
private CinematicKeyframe _preAnimKeyframe;
|
||
//上一个同步事件关键帧
|
||
private CinematicKeyframe _preKeyframeWithSyncEvent;
|
||
private int _curFrame;
|
||
private float _framesAfterPreKey;
|
||
public static bool IsEditorPreview;
|
||
|
||
//剧情播放前的场景音效
|
||
private string _lastSceneMusicName = null;
|
||
|
||
//正在播放的音效
|
||
private int _playingSpeech = -1;
|
||
private int _playingSfx = -1;
|
||
|
||
public void Prepare(CinematicObj obj)
|
||
{
|
||
_curFrame = -1;
|
||
_cObj = obj;
|
||
_preTransKeyframe = null;
|
||
_cObj.Prepare();
|
||
}
|
||
|
||
|
||
public void Destory()
|
||
{
|
||
_vfxbox.Clear();
|
||
if (_cObj != null) _cObj.Destory();
|
||
|
||
StopCinematicAudio();
|
||
}
|
||
|
||
public int GetCurFrame()
|
||
{
|
||
return _curFrame;
|
||
}
|
||
|
||
public Dictionary<int, string> GetVfxDatas()
|
||
{
|
||
Dictionary<int, string> vfxResDict = new Dictionary<int, string>();
|
||
var keyframeList = _cObj.KeyframeList;
|
||
for(int i = 0; i < keyframeList.Count; ++i)
|
||
{
|
||
int keyframe = keyframeList[i].Keyframe;
|
||
var eventDatas = keyframeList[i].EventData;
|
||
for(int j = 0; j < eventDatas.Count; ++j)
|
||
{
|
||
if(eventDatas[j].EventTypeEx == KeyFrameEvent.播放场景特效 ||
|
||
eventDatas[j].EventTypeEx == KeyFrameEvent.播放绑定特效)
|
||
{
|
||
if (vfxResDict.ContainsKey(keyframe))
|
||
vfxResDict[keyframe] = eventDatas[j].Param;
|
||
else
|
||
vfxResDict.Add(keyframe, eventDatas[j].Param);
|
||
}
|
||
}
|
||
}
|
||
|
||
return vfxResDict;
|
||
}
|
||
|
||
public bool IsEnd(int frameNum)
|
||
{
|
||
return _cObj == null || _cObj.IsEndFrame(frameNum);
|
||
}
|
||
|
||
//frameNum 当前第几帧
|
||
public void Update(int frameNum)
|
||
{
|
||
if (_cObj == null) return;
|
||
Update();
|
||
var curFrameData = _cObj.GetKeyframeData(frameNum);
|
||
if(curFrameData != null)
|
||
{
|
||
//上一个同步帧
|
||
if (curFrameData.HasSyncTrans)
|
||
_preKeyframeWithSyncEvent = curFrameData;
|
||
if (curFrameData.TransformEvent != null)
|
||
{
|
||
//直到走到有位移的帧,同步帧置空
|
||
_preTransKeyframe = curFrameData;
|
||
_preKeyframeWithSyncEvent = null;
|
||
}
|
||
if (curFrameData.AnimEvent != null)
|
||
_preAnimKeyframe = curFrameData;
|
||
|
||
}
|
||
else if (frameNum < _curFrame)
|
||
{
|
||
_preTransKeyframe = _cObj.GetPreTransKeyframeData(frameNum);
|
||
_preAnimKeyframe = _cObj.GetPreAnimKeyframeData(frameNum);
|
||
_preKeyframeWithSyncEvent = null;
|
||
}
|
||
|
||
_curFrame = frameNum;
|
||
|
||
if (_preTransKeyframe == null && curFrameData == null && _preAnimKeyframe == null && _preKeyframeWithSyncEvent == null) return;
|
||
|
||
|
||
//处理当前帧数据
|
||
HandleCurFrameData(curFrameData);
|
||
|
||
|
||
//如果当前帧没数据,则处理前后帧的位移
|
||
if (_preTransKeyframe != null)
|
||
{
|
||
//当前帧与上一个关键帧的偏移量
|
||
_framesAfterPreKey = frameNum - _preTransKeyframe.Keyframe;
|
||
HandleTransform(_preTransKeyframe, _framesAfterPreKey);
|
||
}
|
||
|
||
if (_preAnimKeyframe != null)
|
||
{
|
||
HandleAnimation(_preAnimKeyframe, _curFrame);
|
||
}
|
||
|
||
//开始时候同步位置
|
||
if(_preKeyframeWithSyncEvent != null && _preKeyframeWithSyncEvent.HasSyncTrans && _preKeyframeWithSyncEvent.PreEventData == null)
|
||
{
|
||
float durationFrame = _preKeyframeWithSyncEvent.NextTransKeyframe.Keyframe - _preKeyframeWithSyncEvent.Keyframe;
|
||
float deltaFrame = frameNum - _preKeyframeWithSyncEvent.Keyframe;
|
||
_cObj.SetTransform(_preKeyframeWithSyncEvent.TransformEvent, _preKeyframeWithSyncEvent.NextTransKeyframe.TransformEvent, durationFrame, deltaFrame);
|
||
}
|
||
|
||
//结束前同步位置
|
||
if (_preTransKeyframe != null &&
|
||
_preTransKeyframe.NextKeyframe != null &&
|
||
_preTransKeyframe.NextKeyframe.HasSyncTrans)
|
||
{
|
||
//if (_preTransKeyframe.NextKeyframe.TransformEvent == null)
|
||
{
|
||
_preTransKeyframe.NextKeyframe.NeedSetPositionNow = false;
|
||
PreHandleSyncEvent(_preTransKeyframe.NextKeyframe);
|
||
}
|
||
|
||
float durationFrame = _preTransKeyframe.NextKeyframe.Keyframe - _preTransKeyframe.Keyframe;
|
||
float deltaFrame = frameNum - _preTransKeyframe.Keyframe;
|
||
//上一个位移帧的位移,移动到当前帧上面存放的需要同步的位置
|
||
_cObj.SetTransform(_preTransKeyframe.TransformEvent, _preTransKeyframe.NextKeyframe.TransformEvent, durationFrame, deltaFrame);
|
||
}
|
||
}
|
||
|
||
//小于1帧,需要平滑设置位移和动画效果
|
||
public void UpdateSmooth(float deltaFrameLessThanOne)
|
||
{
|
||
//如果当前帧没数据,则处理前后帧的位移
|
||
if (_preTransKeyframe != null)
|
||
{
|
||
//当前帧与上一个关键帧的偏移量
|
||
_framesAfterPreKey = _curFrame + deltaFrameLessThanOne - _preTransKeyframe.Keyframe;
|
||
HandleTransform(_preTransKeyframe, _framesAfterPreKey);
|
||
}
|
||
|
||
if (_preAnimKeyframe != null)
|
||
{
|
||
HandleAnimation(_preAnimKeyframe, _curFrame + deltaFrameLessThanOne);
|
||
}
|
||
}
|
||
|
||
public void Update()
|
||
{
|
||
if (_cObj != null) _cObj.Update();
|
||
_vfxbox.Update(Time.deltaTime);
|
||
}
|
||
|
||
|
||
private void HandleCurFrameData(CinematicKeyframe curFrame)
|
||
{
|
||
for (int i = 0; curFrame != null && i < curFrame.EventData.Count; ++i)
|
||
{
|
||
curFrame.EventData[i].ParentGo = _cObj.GameObject;
|
||
curFrame.EventData[i].CinematicObj = _cObj;
|
||
|
||
//跟随相机事件后续的事件都不做处理
|
||
if (_cObj.IsFollowCamera &&
|
||
curFrame.EventData[i].EventTypeEx != KeyFrameEvent.本地相机同步到剧情坐标 &&
|
||
curFrame.EventData[i].EventTypeEx != KeyFrameEvent.同步到本地角色坐标 &&
|
||
curFrame.EventData[i].EventTypeEx != KeyFrameEvent.同步到本地相机坐标 &&
|
||
curFrame.EventData[i].EventTypeEx != KeyFrameEvent.本地角色同步到剧情坐标)
|
||
continue;
|
||
|
||
if (curFrame.EventData[i].EventTypeEx == KeyFrameEvent.相机跟随)
|
||
_cObj.IsFollowCamera = true;
|
||
|
||
switch (curFrame.EventData[i].EventTypeEx)
|
||
{
|
||
case KeyFrameEvent.加载模型:
|
||
if (!HandleEvent(KeyFrameEvent.加载模型, curFrame.EventData[i]))
|
||
_cObj.LoadPrefab(curFrame.EventData[i].Param, curFrame.EventData[i].EditorParam);
|
||
break;
|
||
case KeyFrameEvent.坐标变换:
|
||
_cObj.SetTransform(curFrame.EventData[i]);
|
||
_cObj.ResetTransState();
|
||
//设置下一个同步事件
|
||
//if(curFrame.NextTransKeyframe != null && curFrame.NextTransKeyframe.HasSyncTrans)
|
||
//{
|
||
// if(_cObj.IsCamera)
|
||
// {
|
||
// HandleEvent(KeyFrameEvent.同步到本地相机坐标, curFrame.NextTransKeyframe);
|
||
// }
|
||
// else
|
||
// {
|
||
// HandleEvent(KeyFrameEvent.同步到本地角色坐标, curFrame.NextTransKeyframe);
|
||
// }
|
||
//}
|
||
break;
|
||
case KeyFrameEvent.播放场景特效:
|
||
{
|
||
var vfx = new FGameObjectVFX();
|
||
vfx.Initialize(curFrame.EventData[i].Param.Replace("\\", "/"), true, false);
|
||
vfx.SetParent(_cObj.GameObject.transform, true);
|
||
vfx.SetLayer(LayerUtils.Default);
|
||
vfx.Play(1);
|
||
_vfxbox.Add(vfx);
|
||
//Debug.LogError("播放场景特效:" + _cObj.GameObject.name + ";;;" + curFrame.EventData[i].Param);
|
||
}
|
||
break;
|
||
case KeyFrameEvent.播放动作:
|
||
if (!HandleEvent(KeyFrameEvent.播放动作, curFrame.EventData[i]))
|
||
{
|
||
_cObj.PlayAnimation(curFrame.EventData[i]);
|
||
//UnityEngine.Debug.LogError("handle KeyFrameEvent.PlayAnim fail, please check!!!");
|
||
}
|
||
break;
|
||
case KeyFrameEvent.播放绑定特效:
|
||
{
|
||
var vfx = new FGameObjectVFX();
|
||
vfx.Initialize(curFrame.EventData[i].Param.Replace("\\", "/"), true, false);
|
||
vfx.SetParent(_cObj.GameObject.transform, true);
|
||
if(_cObj.IsCamera)
|
||
{
|
||
var cam = _cObj.GameObject.GetComponent<Camera>();
|
||
if(cam != null)
|
||
Plugins.Common.UniScene.BaseScene.FixCameraVfx(vfx, cam);
|
||
}
|
||
vfx.SetLayer(LayerUtils.Default);
|
||
vfx.Play(1);
|
||
_vfxbox.Add(vfx);
|
||
//Debug.LogError("播放绑定特效:" + _cObj.GameObject.name+ ";;;"+ curFrame.EventData[i].Param);
|
||
}
|
||
//VFXPlayer.SyncPlayOnTransform(curFrame.EventData[i].Param, _cObj.GameObject.transform, LayerUtils.UIRoleStory);
|
||
break;
|
||
case KeyFrameEvent.播放场景音效:
|
||
if(System.Enum.IsDefined(typeof(AudioTypeCode), curFrame.EventData[i].EditorParam))
|
||
{
|
||
var type = (AudioTypeCode)System.Enum.Parse(typeof(AudioTypeCode), curFrame.EventData[i].EditorParam);
|
||
PlayAudio(type, null, curFrame.EventData[i].Param);
|
||
}
|
||
break;
|
||
case KeyFrameEvent.播放定点音效:
|
||
if (System.Enum.IsDefined(typeof(AudioTypeCode), curFrame.EventData[i].EditorParam))
|
||
{
|
||
var type = (AudioTypeCode)System.Enum.Parse(typeof(AudioTypeCode), curFrame.EventData[i].EditorParam);
|
||
PlayAudio(type, _cObj.GameObject, curFrame.EventData[i].Param);
|
||
}
|
||
break;
|
||
case KeyFrameEvent.暂停:
|
||
float pauseFrame;
|
||
if(float.TryParse(curFrame.EventData[i].Param, out pauseFrame))
|
||
{
|
||
CinematicManager.PauseFrame = pauseFrame;
|
||
}
|
||
break;
|
||
case KeyFrameEvent.设置隐藏或显示: //显示或隐藏
|
||
_cObj.GameObject.SetActive(!curFrame.EventData[i].IsLocalPlayer);
|
||
break;
|
||
case KeyFrameEvent.绑定坐骑: //绑定坐骑
|
||
if(!HandleEvent(KeyFrameEvent.绑定坐骑, curFrame.EventData[i]))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能显示绑定的坐骑");
|
||
break;
|
||
case KeyFrameEvent.同步到本地相机坐标: //同步本地相机位置
|
||
if (!HandleEvent(KeyFrameEvent.同步到本地相机坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能SyncLocalCameraTrans");
|
||
_preKeyframeWithSyncEvent = curFrame;
|
||
_cObj.SetCameraVisiable();
|
||
break;
|
||
case KeyFrameEvent.同步到本地角色坐标: //同步本地角色位置
|
||
if (!HandleEvent(KeyFrameEvent.同步到本地角色坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能SyncLocalCameraTrans");
|
||
_preKeyframeWithSyncEvent = curFrame;
|
||
break;
|
||
case KeyFrameEvent.本地相机同步到剧情坐标: //同步本地角色位置到剧情
|
||
if (!HandleEvent(KeyFrameEvent.本地相机同步到剧情坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能LocalCameraSyncTrans");
|
||
break;
|
||
case KeyFrameEvent.本地角色同步到剧情坐标: //同步本地角色位置到剧情
|
||
if (!HandleEvent(KeyFrameEvent.本地角色同步到剧情坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能LocalPlayerSyncTrans");
|
||
break;
|
||
case KeyFrameEvent.慢动作: //时间缩放
|
||
float scale = 0;
|
||
if(float.TryParse(curFrame.EventData[i].Param, out scale))
|
||
{
|
||
if (scale <= 0) scale = 0.1f;
|
||
if (scale >= 2) scale = 2.0f;
|
||
CinematicManager.Instance.TimeScale = scale;
|
||
Time.timeScale = scale;
|
||
}
|
||
break;
|
||
case KeyFrameEvent.振动效果:
|
||
OnCinematicShakeObj(curFrame.EventData[i]);
|
||
break;
|
||
case KeyFrameEvent.相机运动模糊效果:
|
||
CameraBlurEffect(_cObj.GameObject, curFrame.EventData[i]);
|
||
break;
|
||
case KeyFrameEvent.相机渐黑效果:
|
||
CameraBlackTransEffect(_cObj.GameObject, curFrame.EventData[i]);
|
||
break;
|
||
case KeyFrameEvent.场景物件:
|
||
_cObj.LoadPrefabFromScene(curFrame.EventData[i].Param);
|
||
break;
|
||
//UI效果+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
case KeyFrameEvent.显示对话:
|
||
case KeyFrameEvent.显示boss名字:
|
||
case KeyFrameEvent.显示Texture:
|
||
case KeyFrameEvent.清除Texture:
|
||
case KeyFrameEvent.播放UI特效:
|
||
case KeyFrameEvent.隐藏UI特效:
|
||
case KeyFrameEvent.屏幕渐亮效果:
|
||
case KeyFrameEvent.屏幕渐黑效果:
|
||
case KeyFrameEvent.显示上下边框:
|
||
case KeyFrameEvent.隐藏上下边框:
|
||
case KeyFrameEvent.UI图片Alpha效果:
|
||
case KeyFrameEvent.相机跟随:
|
||
if (!HandleEvent(KeyFrameEvent.UI效果, curFrame.EventData[i]))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能显示Texture");
|
||
break;
|
||
//------------------------------------------------------------------
|
||
default:
|
||
HandleEvent(curFrame.EventData[i].EventTypeEx, curFrame.EventData[i]);
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
private void PlayAudio(AudioTypeCode type, GameObject target, string audioName)
|
||
{
|
||
switch(type)
|
||
{
|
||
case AudioTypeCode.Ambient:
|
||
AudioPlayer.PlayAmbient(target, audioName);
|
||
break;
|
||
case AudioTypeCode.Music:
|
||
{
|
||
if (string.IsNullOrEmpty(_lastSceneMusicName))
|
||
_lastSceneMusicName = AudioPlayer.GetPlayingMusicName();
|
||
AudioPlayer.PlayMusic(audioName, true);
|
||
}
|
||
break;
|
||
case AudioTypeCode.Sfx:
|
||
_playingSfx = AudioPlayer.PlaySfx(target, audioName);
|
||
break;
|
||
case AudioTypeCode.Speech:
|
||
_playingSpeech = AudioPlayer.PlaySpeech(target, audioName);
|
||
break;
|
||
case AudioTypeCode.UI:
|
||
AudioPlayer.PlayUI(audioName);
|
||
break;
|
||
}
|
||
}
|
||
|
||
public void StopCinematicAudio()
|
||
{
|
||
AudioPlayer.ChannelManager.Stop(_playingSfx);
|
||
AudioPlayer.ChannelManager.Stop(_playingSpeech);
|
||
|
||
//恢复之前的背景音乐
|
||
if (!string.IsNullOrEmpty(_lastSceneMusicName))
|
||
AudioPlayer.PlayMusic(_lastSceneMusicName, true);
|
||
|
||
_lastSceneMusicName = null;
|
||
}
|
||
|
||
//预处理同步事件,需要事先获取下一帧同步的位置,不然没有位移变换
|
||
private void PreHandleSyncEvent(CinematicKeyframe curFrame)
|
||
{
|
||
for(int i = 0; i < curFrame.EventData.Count; ++i)
|
||
{
|
||
var eventData = curFrame.EventData[i];
|
||
switch(eventData.EventTypeEx)
|
||
{
|
||
case KeyFrameEvent.同步到本地相机坐标: //同步本地相机位置
|
||
if (!HandleEvent(KeyFrameEvent.同步到本地相机坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能SyncLocalCameraTrans");
|
||
_preKeyframeWithSyncEvent = curFrame;
|
||
_cObj.SetCameraVisiable();
|
||
break;
|
||
case KeyFrameEvent.同步到本地角色坐标: //同步本地角色位置
|
||
if (!HandleEvent(KeyFrameEvent.同步到本地角色坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能SyncLocalCameraTrans");
|
||
_preKeyframeWithSyncEvent = curFrame;
|
||
break;
|
||
case KeyFrameEvent.本地相机同步到剧情坐标: //同步本地角色位置到剧情
|
||
if (!HandleEvent(KeyFrameEvent.本地相机同步到剧情坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能LocalCameraSyncTrans");
|
||
break;
|
||
case KeyFrameEvent.本地角色同步到剧情坐标: //同步本地角色位置到剧情
|
||
if (!HandleEvent(KeyFrameEvent.本地角色同步到剧情坐标, curFrame))
|
||
UnityEngine.Debug.LogError("请先运行游戏才能LocalPlayerSyncTrans");
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
//处理事件
|
||
private bool HandleEvent(KeyFrameEvent eventType, ICinematic eventData)
|
||
{
|
||
bool ret = false;
|
||
Func<ICinematic, bool> handler = CinematicManager.Instance.GetEventHandler(eventType);
|
||
if (handler != null)
|
||
{
|
||
ret = handler(eventData);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
//处理位移
|
||
private void HandleTransform(CinematicKeyframe frameWithTransData, float frameDelta)
|
||
{
|
||
if (frameDelta == 0) return;
|
||
if(frameWithTransData.TransformEvent == null)
|
||
{
|
||
for (int i = 0; frameWithTransData != null && i < frameWithTransData.EventData.Count; ++i)
|
||
{
|
||
if(frameWithTransData.EventData[i].EventTypeEx == KeyFrameEvent.坐标变换)
|
||
{
|
||
frameWithTransData.TransformEvent = frameWithTransData.EventData[i];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(frameWithTransData.TransformEvent != null)
|
||
{
|
||
var nextKeyframe = frameWithTransData.NextKeyframe;
|
||
//下一个关键帧是同步帧,则不做曲线变换,直接跳过
|
||
if (nextKeyframe != null && nextKeyframe.HasSyncTrans)
|
||
{
|
||
//if(nextKeyframe.TransformEvent == null)
|
||
PreHandleSyncEvent(nextKeyframe);
|
||
return;
|
||
}
|
||
_cObj.SetTransformCurveTo(frameWithTransData.TransformEvent, frameWithTransData, frameWithTransData.Keyframe, frameDelta);
|
||
}
|
||
}
|
||
|
||
//处理动作,逐帧播放的动作
|
||
private void HandleAnimation(CinematicKeyframe frameWithAnimData, float curFrame)
|
||
{
|
||
if(frameWithAnimData.AnimEvent == null)
|
||
{
|
||
for (int i = 0; frameWithAnimData != null && i < frameWithAnimData.EventData.Count; ++i)
|
||
{
|
||
switch (frameWithAnimData.EventData[i].EventTypeEx)
|
||
{
|
||
case KeyFrameEvent.播放动作:
|
||
frameWithAnimData.AnimEvent = frameWithAnimData.EventData[i];
|
||
break;
|
||
|
||
default:
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
_cObj.PlayAnimationByFrame(frameWithAnimData.AnimEvent, frameWithAnimData.Keyframe, curFrame);
|
||
}
|
||
|
||
//运动模糊效果
|
||
private void CameraBlurEffect(GameObject cameraGo, CinematicEventData eventData)
|
||
{
|
||
float duration = 0;
|
||
float strenth = 3;
|
||
if (!float.TryParse(eventData.Param, out duration))
|
||
{
|
||
duration = 2.0f;
|
||
}
|
||
if (!float.TryParse(eventData.EditorParam, out strenth))
|
||
{
|
||
strenth = 3f;
|
||
}
|
||
var blurScript = RequireComponent<CinematicSportBlur>(_cObj.GameObject);
|
||
blurScript.StartBlur(duration, strenth);
|
||
}
|
||
|
||
//相机渐黑效果
|
||
private void CameraBlackTransEffect(GameObject cameraGo, CinematicEventData eventData)
|
||
{
|
||
float duration = 0;
|
||
if (!float.TryParse(eventData.Param, out duration))
|
||
{
|
||
duration = 2.0f;
|
||
}
|
||
var script = RequireComponent<CinematicFadeBlack>(_cObj.GameObject);
|
||
script.StartTrans(duration);
|
||
}
|
||
|
||
//振动效果
|
||
public bool OnCinematicShakeObj(CinematicEventData eventData)
|
||
{
|
||
float duration = 0;
|
||
float strenth = 3;
|
||
if (!float.TryParse(eventData.Param, out duration))
|
||
{
|
||
duration = 2.0f;
|
||
}
|
||
if (!float.TryParse(eventData.EditorParam, out strenth))
|
||
{
|
||
strenth = 3f;
|
||
}
|
||
var shakeScript = RequireComponent<CinematicShake>(eventData.ParentGo);
|
||
shakeScript.StartShake(duration, strenth);
|
||
|
||
return true;
|
||
}
|
||
|
||
private T RequireComponent<T>(GameObject go) where T: MonoBehaviour
|
||
{
|
||
T script = go.GetComponent<T>();
|
||
if (script == null)
|
||
script = go.AddComponent<T>();
|
||
|
||
return script;
|
||
}
|
||
}
|
||
}
|
||
|