using Thousandto.Core.Asset; using Thousandto.Core.Base; using System.Collections.Generic; using UnityEditor; using UnityEngine; using Thousandto.Core.PostEffect; using Thousandto.Plugins.Common.UniScene; using Thousandto.Launcher.ExternalLibs; using Thousandto.SkillEditor.Support; namespace Thousandto.DIY.UniScene { public class FlyTeleportScriptEditor { private string[] _playerNames = new string[] { "学生", "拳师", "大锤", "剑客", "卡牌" }; private int _playerSelectIndex = 0; private int _nowLoadedPlayer = -1; public Transform UserRoot = null; public const string UserRootName = "[UserRoot]"; public GameObject _player = null; public AnimationPlayer _playerAnim = null; public float FrontTime = 0f; public Vector3 _oriForward = Vector3.zero; public Vector3 _targetForward = Vector3.zero; public float timer = 0f; public bool IsPlay = false; public List ItweenPaths = null; public List> PlayCurves = null; public int PlayNodeIndex = 0; public int PlayPathIndex = 0; private List VfxList = new List(); public FlyTeleportEditorScript _target; public void SetTarget(FlyTeleportEditorScript target) { //i like bold handle labels since I'm getting old: _target = target; var rootGo = GameObject.Find(UserRootName); if (rootGo == null) { rootGo = new GameObject(UserRootName); } UserRoot = rootGo.transform; FrontTime = Time.realtimeSinceStartup; } void OnDisable() { } void OnSceneGUI() { for (int i = 0; i < _target.transform.childCount; ++i) { Transform trans = _target.transform.GetChild(i); FlyTeleportNodeScript script = trans.GetComponent(); trans.position = Handles.PositionHandle(trans.position, Quaternion.identity); } } public FlyTeleportNodeScript CreateNewNode() { string name = "Node_1"; FlyTeleportNodeScript lastNode = null; if (_target.transform.childCount > 0) { name = string.Format("Node_{0}", _target.transform.childCount + 1); lastNode = _target.transform.GetChild(_target.transform.childCount - 1).GetComponent(); } var nodeGo = new GameObject(name); nodeGo.transform.parent = _target.transform; UnityUtils.Reset(nodeGo.transform); var nodeScript = UnityUtils.RequireComponent(nodeGo); if (lastNode != null) { nodeScript.transform.position = lastNode.transform.position; nodeScript.EnterAnim = lastNode.EnterAnim; nodeScript.EnterAnimSpeed = lastNode.EnterAnimSpeed; nodeScript.EnterIsLoop = lastNode.EnterIsLoop; nodeScript.LeaveAnim = lastNode.LeaveAnim; nodeScript.LeaveAnimSpeed = lastNode.LeaveAnimSpeed; nodeScript.LeaveIsLoop = lastNode.LeaveIsLoop; nodeScript.WaitTime = lastNode.WaitTime; nodeScript.MoveTime = lastNode.MoveTime; nodeScript.MoveCurve = InitNormalCurve(); nodeScript.Distance = lastNode.Distance; nodeScript.Percent = lastNode.Percent; nodeScript.BreakPoint = lastNode.BreakPoint; nodeScript.CameraYaw = lastNode.CameraYaw; nodeScript.CameraPitch = lastNode.CameraPitch; nodeScript.CameraFlowDis = lastNode.CameraFlowDis; nodeScript.CameraOffsetX = lastNode.CameraOffsetX; nodeScript.CameraOffsetY = lastNode.CameraOffsetY; nodeScript.CameraCurve = lastNode.CameraCurve; nodeScript.CameraShake = lastNode.CameraShake; nodeScript.ShakePower = lastNode.ShakePower; nodeScript.ShakeTime = lastNode.ShakeTime; nodeScript.ShakeType = lastNode.ShakeType; nodeScript.ShakeCurve = lastNode.ShakeCurve; nodeScript.CameraBlur = lastNode.CameraBlur; nodeScript.BlurStart = lastNode.BlurStart; nodeScript.BlurEnd = lastNode.BlurEnd; nodeScript.BlurTime = lastNode.BlurTime; nodeScript.VfxType = lastNode.VfxType; nodeScript.VfxID = lastNode.VfxID; nodeScript.VfxIsLoop = lastNode.VfxIsLoop; nodeScript.VfxLifeTime = lastNode.VfxLifeTime; nodeScript.VfxSlot = lastNode.VfxSlot; } else { nodeScript.transform.position = Vector3.zero; nodeScript.EnterAnim = string.Empty; nodeScript.EnterAnimSpeed = 1f; nodeScript.EnterIsLoop = false; nodeScript.LeaveAnim = string.Empty; nodeScript.LeaveAnimSpeed = 1f; nodeScript.LeaveIsLoop = false; nodeScript.WaitTime = 0f; nodeScript.MoveTime = 1f; nodeScript.MoveCurve = InitNormalCurve(); nodeScript.Distance = 0f; nodeScript.Percent = 0f; nodeScript.BreakPoint = false; nodeScript.CameraYaw = 0; nodeScript.CameraPitch = 25f; nodeScript.CameraFlowDis = 10f; nodeScript.CameraOffsetX = 0f; nodeScript.CameraOffsetY = 1.5f; nodeScript.CameraCurve = InitNormalCurve(); nodeScript.CameraShake = false; nodeScript.ShakePower = 1f; nodeScript.ShakeTime = 1f; nodeScript.ShakeType = VFXCameraShakerType.Default; nodeScript.ShakeCurve = InitNormalCurve(); nodeScript.CameraBlur = false; nodeScript.BlurStart = 0f; nodeScript.BlurEnd = 0f; nodeScript.BlurTime = 1f; nodeScript.VfxType = ModelTypeCode.OtherVFX; nodeScript.VfxID = 0; nodeScript.VfxIsLoop = false; nodeScript.VfxLifeTime = 0f; nodeScript.VfxSlot = Slot.Origin; } return nodeScript; } public AnimationCurve InitNormalCurve() { AnimationCurve curve = new AnimationCurve(); curve.AddKey(0f, 0f); curve.AddKey(1f, 1f); return curve; } public void OnGUI() { if (_target == null) return; if (GUILayout.Button("删除")) { GameObject.DestroyImmediate(_target.gameObject); FlyTeleportDataManager.Remove(_target.ID); _target = null; return; } GUILayout.TextField(_target.ID.ToString()); GUILayout.TextField(_target.MapName); if (_target.transform.childCount < 2) { //创建到2个节点 for (int i = 2; i > _target.transform.childCount; --i) { CreateNewNode(); } } if (GUILayout.Button("添加节点")) { CreateNewNode(); } if (Application.isPlaying) { _playerSelectIndex = EditorGUILayout.Popup(_playerSelectIndex, _playerNames); if (_nowLoadedPlayer != _playerSelectIndex) { _nowLoadedPlayer = _playerSelectIndex; if (UserRoot.childCount > 0) { while (UserRoot.childCount > 0) { GameObject.DestroyImmediate(UserRoot.GetChild(0).gameObject); } } int userID = 0; int weaponIDL = 0; int weaponIDR = 0; switch (_playerSelectIndex) { case 0: userID = 1; weaponIDR = 1; break; case 1: userID = 101; weaponIDL = 101; weaponIDR = 102; break; case 2: userID = 201; weaponIDR = 201; break; case 3: userID = 301; weaponIDL = 301; weaponIDR = 302; break; case 4: userID = 401; weaponIDR = 401; break; } var weaponLPath = AssetUtils.GetModelAssetPath(ModelTypeCode.Weapon, weaponIDL); var weaponRPath = AssetUtils.GetModelAssetPath(ModelTypeCode.Weapon, weaponIDR); LoadUser(AssetUtils.GetModelAssetPath(ModelTypeCode.Player, userID), weaponLPath, weaponRPath); CreatePlayer(); } if (GUILayout.Button("播放测试")) { IsPlay = true; timer = 0f; if (_playerAnim != null) { _playerAnim.Stop(); } PlayCurves = _target.CalculatePathNodePercent(); ItweenPaths = new List(); for (int i = 0; i < PlayCurves.Count; ++i) { Vector3[] itweenPath = new Vector3[PlayCurves[i].Count]; for (int j = 0; j < PlayCurves[i].Count; ++j) { itweenPath[j] = PlayCurves[i][j].transform.position; } itweenPath = iTween.PathControlPointGenerator(itweenPath); ItweenPaths.Add(itweenPath); } PlayNodeIndex = 0; PlayPathIndex = 0; var startNode = PlayCurves[0][0]; PlayEnterEffct(startNode); FlyEditorCamera.Camera.CurYaw = startNode.CameraYaw; FlyEditorCamera.Camera.CurPitch = startNode.CameraPitch; FlyEditorCamera.Camera.CurDis = startNode.CameraFlowDis; FlyEditorCamera.Camera.CurOffsetX = startNode.CameraOffsetX; FlyEditorCamera.Camera.CurOffsetY = startNode.CameraOffsetY; var nextNode = PlayCurves[0][1]; var dir = nextNode.transform.position - startNode.transform.position; dir.y = 0f; _player.transform.forward = dir.normalized; _oriForward = dir.normalized; _targetForward = _oriForward; } } } public void UpdateEditor() { float dt = Time.realtimeSinceStartup - FrontTime; FrontTime = Time.realtimeSinceStartup; for(int i = VfxList.Count - 1; i >= 0; --i) { if(VfxList[i].Update(dt)) { VfxList.RemoveAt(i); } } if (Application.isPlaying) { EditorVFXPlayer.Instance.Update(); if (_playerAnim != null) { _playerAnim.Update(dt); } if (IsPlay) { if (PlayPathIndex < PlayCurves.Count) { var path = PlayCurves[PlayPathIndex]; if (PlayNodeIndex < path.Count) { float noncePercent = path[PlayNodeIndex].Percent; if (PlayNodeIndex == 0) { noncePercent = 0f; } float targetPercent = 1f; if ((PlayNodeIndex + 1) < path.Count - 1) { targetPercent = path[PlayNodeIndex + 1].Percent; } float nonceYaw = path[PlayNodeIndex].CameraYaw; float noncePitch = path[PlayNodeIndex].CameraPitch; float nonceFlowDis = path[PlayNodeIndex].CameraFlowDis; float nonceOffsetX = path[PlayNodeIndex].CameraOffsetX; float nonceOffsetY = path[PlayNodeIndex].CameraOffsetY; var nonceCameraCurve = path[PlayNodeIndex].CameraCurve; float targetYaw = path[PlayNodeIndex + 1].CameraYaw; float targetPitch = path[PlayNodeIndex + 1].CameraPitch; float targetFlowDis = path[PlayNodeIndex + 1].CameraFlowDis; float targetOffsetX = path[PlayNodeIndex + 1].CameraOffsetX; float targetOffsetY = path[PlayNodeIndex + 1].CameraOffsetY; float moveTime = path[PlayNodeIndex].MoveTime; float waitTime = path[PlayNodeIndex].WaitTime; float curveTime = path[PlayNodeIndex].MoveCurve.keys[path[PlayNodeIndex].MoveCurve.keys.Length - 1].time; if (timer <= waitTime && (timer + dt) > waitTime) { //离开等待状态 _playerAnim.Play(path[PlayNodeIndex].LeaveAnim, AnimationPartType.AllBody, path[PlayNodeIndex].LeaveIsLoop ? WrapMode.Loop : WrapMode.Once, true, 0.2f, path[PlayNodeIndex].LeaveAnimSpeed); } var frontTimer = timer; timer += dt; if (path[PlayNodeIndex].CameraBlur && path[PlayNodeIndex].BlurWaitTime > 0f && timer >= path[PlayNodeIndex].BlurWaitTime && frontTimer < path[PlayNodeIndex].BlurWaitTime && FlyEditorCamera.RadiaBlurEffect != null) { FlyEditorCamera.RadiaBlurEffect.Play(path[PlayNodeIndex].BlurStart, path[PlayNodeIndex].BlurEnd, path[PlayNodeIndex].BlurTime); } if (timer > waitTime) { float lerpValue = path[PlayNodeIndex].MoveCurve.Evaluate(Mathf.Clamp01((timer - waitTime) / moveTime) * curveTime); FlyEditorCamera.Camera.CurYaw = Mathf.Lerp(nonceYaw, targetYaw, nonceCameraCurve.Evaluate(lerpValue)); FlyEditorCamera.Camera.CurPitch = Mathf.Lerp(noncePitch, targetPitch, nonceCameraCurve.Evaluate(lerpValue)); FlyEditorCamera.Camera.CurDis = Mathf.Lerp(nonceFlowDis, targetFlowDis, nonceCameraCurve.Evaluate(lerpValue)); FlyEditorCamera.Camera.CurOffsetX = Mathf.Lerp(nonceOffsetX, targetOffsetX, nonceCameraCurve.Evaluate(lerpValue)); FlyEditorCamera.Camera.CurOffsetY = Mathf.Lerp(nonceOffsetY, targetOffsetY, nonceCameraCurve.Evaluate(lerpValue)); _player.transform.forward = Vector3.Lerp(_oriForward, _targetForward, nonceCameraCurve.Evaluate(lerpValue)); lerpValue = Mathf.Clamp01(Mathf.Lerp(noncePercent, targetPercent, lerpValue)); _player.transform.position = iTween.Interp(ItweenPaths[PlayPathIndex], lerpValue); if (timer >= (moveTime + waitTime)) { ++PlayNodeIndex; if (PlayNodeIndex >= path.Count - 1) { ++PlayPathIndex; PlayNodeIndex = 0; timer -= (moveTime + waitTime); if (PlayPathIndex < PlayCurves.Count) { var nextPath = PlayCurves[PlayPathIndex]; var playNode = nextPath[PlayNodeIndex]; PlayEnterEffct(playNode); var nextNode = nextPath[PlayNodeIndex + 1]; var dir = nextNode.transform.position - playNode.transform.position; dir.y = 0f; _player.transform.forward = dir.normalized; _oriForward = dir.normalized; _targetForward = dir.normalized; } } else { timer -= (moveTime + waitTime); if (PlayNodeIndex < path.Count) { var playNode = path[PlayNodeIndex]; PlayEnterEffct(playNode); if (PlayNodeIndex < path.Count - 1) { var nextNode = path[PlayNodeIndex + 1]; var dir = nextNode.transform.position - playNode.transform.position; dir.y = 0f; _oriForward = _targetForward; _targetForward = dir.normalized; } } } } } } } else { var endNode = PlayCurves[PlayCurves.Count - 1][PlayCurves[PlayCurves.Count - 1].Count - 1]; PlayEnterEffct(endNode); IsPlay = false; } } else { if (Selection.activeGameObject != null) { var script = Selection.activeGameObject.GetComponent(); if (script != null) { _player.transform.position = script.transform.position; FlyEditorCamera.Camera.CurYaw = script.CameraYaw; FlyEditorCamera.Camera.CurPitch = script.CameraPitch; FlyEditorCamera.Camera.CurDis = script.CameraFlowDis; FlyEditorCamera.Camera.CurOffsetX = script.CameraOffsetX; FlyEditorCamera.Camera.CurOffsetY = script.CameraOffsetY; } } if (VfxList.Count > 0) { for (int i = VfxList.Count - 1; i >= 0; --i) { VfxList[i].Destory(); } VfxList.Clear(); } } } } void PlayEnterEffct(FlyTeleportNodeScript script) { if (_playerAnim != null) { _playerAnim.Play(script.EnterAnim, AnimationPartType.AllBody, script.EnterIsLoop ? WrapMode.Loop : WrapMode.Once, true, 0.2f, script.EnterAnimSpeed); } if (script.CameraShake && FlyEditorCamera.CameraShaker != null) { var curve = script.ShakeCurve; if (curve != null) { var task = new VFXCameraShakeTask(FlyEditorCamera.CameraShaker); task.Curve = curve; task.TotalTime = script.ShakeTime; task.Type = script.ShakeType; task.Time = 0; task.Power = script.ShakePower; FlyEditorCamera.CameraShaker.AddTask(task); } } if (script.CameraBlur && script.BlurWaitTime <= 0f && FlyEditorCamera.RadiaBlurEffect != null) { FlyEditorCamera.RadiaBlurEffect.Play(script.BlurStart, script.BlurEnd, script.BlurTime); } if(script.VfxID > 0) { var hitTrans = SlotUtils.GetSlotTransform(_player.transform, script.VfxSlot); var resPath = AssetUtils.GetModelAssetPath(script.VfxType, script.VfxID); var vfx = new VfxInst(); vfx.Vfx = EditorVFXPlayer.Instance.PlayVFX(resPath, hitTrans); vfx.LifeTime = script.VfxLifeTime; VfxList.Add(vfx); } } public void LoadUser(string path, string weaponLPath, string weaponRPath) { FlyEditorCamera.CreateCamera(false); GameObject prefab = ResourcesEx.Load(path) as GameObject; if (prefab != null) { GameObject model = (GameObject)GameObject.Instantiate(prefab); model.transform.parent = UserRoot; UnityUtils.Reset(model.transform); FlyEditorCamera.Camera.SetTarget(model.transform); if (!string.IsNullOrEmpty(weaponLPath)) { var wPrefab = ResourcesEx.Load(weaponLPath) as GameObject; if (wPrefab != null) { var slot = SlotUtils.FindSlotTransform(model.transform, Slot.LeftWeapon); if (slot != null) { var wModel = (GameObject)GameObject.Instantiate(wPrefab); wModel.transform.parent = slot; UnityUtils.Reset(wModel.transform); } } } if (!string.IsNullOrEmpty(weaponRPath)) { var wPrefab = ResourcesEx.Load(weaponRPath) as GameObject; if (wPrefab != null) { var slot = SlotUtils.FindSlotTransform(model.transform, Slot.RightWeapon); if (slot != null) { var wModel = (GameObject)GameObject.Instantiate(wPrefab); wModel.transform.parent = slot; UnityUtils.Reset(wModel.transform); } } } } } private bool CreatePlayer() { var playerRoot = UserRoot; if (playerRoot == null) return false; if (playerRoot.childCount <= 0) return false; var newPlayer = playerRoot.GetChild(0).gameObject; if (_player != newPlayer) { _player = newPlayer; _playerAnim = CreateAnimPlayer(_player.transform); } return true; } //创建动作播放器 public AnimationPlayer CreateAnimPlayer(Transform model) { AnimationPlayer ret = null; if (model != null) { var animList = UnityUtils.GetComponentInChildren_IgnoreActiveStatus(model); if (animList != null) { var anim = UnityUtils.RequireComponent(animList.gameObject); anim.AddClips(AnimInfo.GetClips(anim.AnimAssetPathDic.Values)); ret = new AnimationPlayer(anim); ret.CullingType = AnimatorCullingMode.CullCompletely; } } return ret; } private class VfxInst { public EditorVFXScript Vfx = null; public float LifeTime = 0f; private float _timer = 0f; public bool Update(float dt) { if (Vfx.IsEnd) return true; if(LifeTime > 0) { _timer += dt; if(_timer >= LifeTime) { Destory(); return true; } } return false; } public void Destory() { if(Vfx != null) { Vfx.Stop(); Vfx = null; } } } } }