From 6eb915c129fc90c6f4c82ae097dd6ffad5239efc Mon Sep 17 00:00:00 2001 From: chai Date: Mon, 25 Jan 2021 14:28:30 +0800 Subject: +scripts --- Client/Assets/Scripts/UICommon/XSthCollector.cs | 351 ++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 Client/Assets/Scripts/UICommon/XSthCollector.cs (limited to 'Client/Assets/Scripts/UICommon/XSthCollector.cs') diff --git a/Client/Assets/Scripts/UICommon/XSthCollector.cs b/Client/Assets/Scripts/UICommon/XSthCollector.cs new file mode 100644 index 00000000..df3b7a12 --- /dev/null +++ b/Client/Assets/Scripts/UICommon/XSthCollector.cs @@ -0,0 +1,351 @@ +using UILib; +using UnityEngine; +using System.Collections.Generic; +using XUtliPoolLib; + +public class XSthCollector : XUIObject, IXUISthCollector +{ + public List SthList = new List(); + + public Vector3 Src = new Vector3(0, 0, 0); + public Vector3 Des = new Vector3(-450, -280, 0); + + public int Count = 15; + public float EmitInterval = 0.01f; + + public int EmitDegreeRange = 300; + public float MinEmitSpeed = 1900; + public float MaxEmitSpeed = 2100; + + public float SrcAcceleration = 20000; + public float DesAcceleration = 8000; + public float SthAcceleration = 10000; + + public float MinStartFindDesTime = 0.3f; + public float MaxStartFindDesTime = 0.6f; + + public float MinIdleSpeed = 30; + List m_SthList = null; + bool m_bActive; + + //string m_CurName; + GameObject m_CurSthGo; + + //Dictionary> m_SthListMap = new Dictionary>(); + Dictionary m_SthTplMap = new Dictionary(); + List m_ExternalSthList = new List(); + + Vector3 m_Direction; + SthArrivedEventHandler m_SthArrivedEventHandler; + CollectFinishEventHandler m_CollectFinishEventHandler; + + int m_ArrivedCount; + void Awake() + { + for (int i = 0; i < SthList.Count; ++i) + { + m_SthTplMap.Add(SthList[i].name, SthList[i]); + SthList[i].SetActive(false); + } + m_Direction = (Des - Src).normalized; + } + void OnEnable() + { + m_bActive = false; + + if (m_SthList != null) + { + for (int i = 0; i < m_SthList.Count; ++i) + { + m_SthList[i].bEnable = false; + } + } + } + + public void SetPosition(Vector3 srcGlobalPos, Vector3 desGlobalPos) + { + Src = transform.worldToLocalMatrix * srcGlobalPos; + Des = transform.worldToLocalMatrix * desGlobalPos; + m_Direction = (Des - Src).normalized; + } + + public void SetSth(List goes) + { + for (int i = m_ExternalSthList.Count; i < goes.Count; ++i) + { + XSth sth = new XSth(); + m_ExternalSthList.Add(sth); + } + for (int i = m_ExternalSthList.Count - 1; i >= goes.Count; --i) + { + m_ExternalSthList.RemoveAt(i); + } + m_SthList = m_ExternalSthList; + + for (int i = 0; i < m_ExternalSthList.Count; ++i) + { + m_SthList[i].Go = goes[i]; + goes[i].SetActive(false); + m_SthList[i].bEnable = false; + } + } + + public void SetSth(string name) + { + //if (m_SthList != null && m_CurName != name) + //{ + // for (int i = 0; i < m_SthList.Count; ++i) + // { + // m_SthList[i].bEnable = false; + // } + //} + //if (!m_SthTplMap.TryGetValue(name, out m_CurSthGo)) + //{ + // Debug.LogError("Cant find tpl name: " + name); + // return; + //} + + //if (!m_SthListMap.TryGetValue(name, out m_SthList)) + //{ + // m_SthList = new List(); + // m_SthListMap.Add(name, m_SthList); + //} + + //_GenerateSth(); + } + + private void _GenerateSth() + { + if (m_SthList.Count != Count) + { + m_CurSthGo.SetActive(true); + for (int i = m_SthList.Count; i < Count; ++i) + { + XSth sth = new XSth(); + GameObject go = UnityEngine.Object.Instantiate(m_CurSthGo) as GameObject; + go.transform.parent = transform; + go.transform.localScale = Vector3.one; + sth.Go = go; + go.SetActive(false); + m_SthList.Add(sth); + } + m_CurSthGo.SetActive(false); + + for (int i = m_SthList.Count - 1; i >= Count; --i) + { + m_SthList[i].Destroy(); + m_SthList.RemoveAt(i); + } + } + + for (int i = 0; i < m_SthList.Count; ++i) + { + m_SthList[i].bEnable = false; + } + } + + [ContextMenu("Emit")] + public void Emit() + { + float fDelayTime = 0.0f; + for (int i = 0; i < m_SthList.Count; ++i, fDelayTime += EmitInterval) + { + XSth sth = m_SthList[i]; + sth.DelayTime = fDelayTime; + + sth.Speed = XCommon.singleton.RandomFloat(MinEmitSpeed, MaxEmitSpeed) * _RandEmitDir(); + sth.StartFindDesTime = XCommon.singleton.RandomFloat(MinStartFindDesTime, MaxStartFindDesTime); + sth.Time = 0.0f; + sth.MinIdleSpeed = MinIdleSpeed; + sth.Go.transform.localPosition = Src;// transform.worldToLocalMatrix* Src; + sth.Des = Des;// transform.worldToLocalMatrix* Des; + sth.bEnable = true; + } + m_bActive = true; + m_ArrivedCount = 0; + } + + Vector3 _RandEmitDir() + { + float radRange = EmitDegreeRange * Mathf.Deg2Rad; + float rad = XCommon.singleton.RandomFloat(radRange) - radRange / 2; + float sinA = Mathf.Sin(rad); + float cosA = Mathf.Cos(rad); + + Vector3 vec = m_Direction; + vec.x = m_Direction.x * cosA - m_Direction.y * sinA; + vec.y = m_Direction.x * sinA + m_Direction.y * cosA; + + return vec; + } + + Vector3 _GetAcceleration(XSth sth, float t) + { + Vector3 curPos = sth.Go.transform.localPosition; + Vector3 acc = Vector3.zero; + + Vector3 gDes = (Des - curPos).normalized; + if (sth.State == XSth.SthState.FLAME_OUT) + { + acc += gDes * DesAcceleration; + } + + Vector3 gSrc = (Src - curPos).normalized; + if (sth.State == XSth.SthState.IDLE) + { + acc += gSrc * SrcAcceleration; + } + + if (sth.State == XSth.SthState.DIRECTION_ADJUSTING) + { + float desCross = gDes.x * sth.Speed.y - gDes.y * sth.Speed.x; + + Vector3 perpendicular = new Vector3(-sth.Speed.y, sth.Speed.x, sth.Speed.z); + if ((perpendicular.x * sth.Speed.y - perpendicular.y * sth.Speed.x) * desCross < 0) + { + perpendicular.x = -perpendicular.x; + perpendicular.y = -perpendicular.y; + } + perpendicular = perpendicular.normalized * SthAcceleration; + acc += perpendicular; + } + + return acc; + } + + void Update() + { + if (!m_bActive) + return; + + m_bActive = false; + for (int i = 0; i < m_SthList.Count; ++i) + { + XSth sth = m_SthList[i]; + if (!sth.bEnable) + continue; + m_bActive = true; + + if (!sth.Update(Time.deltaTime)) + { + if (m_SthArrivedEventHandler != null) + m_SthArrivedEventHandler(m_ArrivedCount++); + } + + if (sth.DelayTime <= 0.0f) + sth.Acceleration = _GetAcceleration(sth, Time.deltaTime); + } + + if (!m_bActive && m_CollectFinishEventHandler != null) + m_CollectFinishEventHandler(); + } + + public void RegisterSthArrivedEventHandler(SthArrivedEventHandler eventHandler) + { + m_SthArrivedEventHandler = eventHandler; + } + + public void RegisterCollectFinishEventHandler(CollectFinishEventHandler eventHandler) + { + m_CollectFinishEventHandler = eventHandler; + } +} + +public class XSth +{ + public enum SthState + { + IDLE, + DIRECTION_ADJUSTING, + FLAME_OUT + } + public GameObject Go; + public Vector3 Speed; + public float MinIdleSpeed; + public Vector3 Acceleration; + public float Time; + public float DelayTime; + public float StartFindDesTime; + public Vector3 Des; + public SthState State; + + private bool m_bEnable = false; + public bool bEnable + { + get { return m_bEnable; } + set + { + m_bEnable = value; + Acceleration = Vector3.zero; + State = SthState.IDLE; + if (!m_bEnable) + { + Go.SetActive(false); + } + } + } + + public void Destroy() + { + UnityEngine.Object.Destroy(Go); + } + + public bool Update(float t) + { + if (!bEnable) + return bEnable; + + if (DelayTime > 0.0f) + { + DelayTime -= t; + if (DelayTime > 0.0f) + return true; + t = -DelayTime; + } + + Time += t; + + Vector3 newSpeed = Speed + (Acceleration * t); + + Vector3 pos = Go.transform.localPosition; + + if (State == SthState.IDLE) + { + if (newSpeed.x * Speed.x + newSpeed.y * Speed.y <= 0) + { + // 速度减到回落了,避免这种情况,让它以极低速度运行 + newSpeed = Speed.normalized * MinIdleSpeed; + } + + if (Time > StartFindDesTime) + { + State = SthState.DIRECTION_ADJUSTING; + } + } + if (State == SthState.DIRECTION_ADJUSTING) + { + Vector3 desDir = Des - pos; + float crossProduct0 = Speed.x * desDir.y - Speed.y * desDir.x; + float crossProduct1 = desDir.x * newSpeed.y - desDir.y * newSpeed.x; + + if (crossProduct0 * crossProduct1 > 0) + { + newSpeed = newSpeed.magnitude * desDir.normalized; + State = SthState.FLAME_OUT; + } + } + if (!Go.activeSelf) + Go.SetActive(true); + + Speed = newSpeed; + + Vector3 newPos = pos + Speed * t; + if ((newPos - pos).sqrMagnitude >= (Des - pos).sqrMagnitude) + bEnable = false; + else + Go.transform.localPosition = newPos; + + return bEnable; + } +} + -- cgit v1.1-26-g67d0