using GCGame.Table; using UnityEngine; public class SkillCircleProjector : MonoBehaviour { public Texture big_Red; public Texture big_Yellow; public MeshRenderer CircleEffect; public MeshRenderer ControlEffect; public Transform ControlRotation; private Tab_SkillEx currentSkill; public Texture Line_Red; //直线 public Texture Line_Yellow; private readonly Quaternion oldRotation = Quaternion.Euler(0, 0, 0); public Texture Ring_Red; //圆环 public Texture Ring_Yellow; public Texture SelectInner_Red; //扇形 public Texture SelectInner_Yellow; public Texture Trip_Red; //陷阱 public Texture Trip_Yellow; private void Awake() { DontDestroyOnLoad(gameObject); } private void LateUpdate() { var mainPlayer = ObjManager.Instance.MainPlayer; if (mainPlayer) transform.position = mainPlayer.Position; } public Vector2 InitSkillInfo(Tab_SkillEx skillEx, Vector2 defaultPoint) { if (Singleton.Instance.MainPlayer == null) return Vector2.zero; var x = Singleton.Instance.MainPlayer.transform.position.x; var y = Singleton.Instance.MainPlayer.transform.position.y + 0.5f; var z = Singleton.Instance.MainPlayer.transform.position.z; transform.position = new Vector3(x, y, z); var selector = TableManager.GetSkillTargetSelectorByID(skillEx.GetSelectorIdbyIndex(0)); var type = GetSkillType(skillEx, selector); if (type == null) { gameObject.SetActive(false); return Vector2.zero; } else { currentSkill = skillEx; if (type != 5) defaultPoint = defaultPoint.normalized; SetCircleTex(false, skillEx.Radius * 2); switch (type) { case -1: return InitCircleRange(skillEx, null, defaultPoint); case 1: return InitCircleRange(skillEx, selector, defaultPoint); case 2: return InitSectorRange(skillEx, selector, defaultPoint); case 3: return InitLineRange(skillEx, selector, defaultPoint); case 4: return InitRingRange(skillEx, selector, defaultPoint); case 5: return InitTripRange(skillEx, selector, defaultPoint); default: gameObject.SetActive(false); return Vector2.zero; } } } //范围参数1(无则填-1 圆形扫描的半径 扇形扫描的半径 直线扫描的长度距离 环形的内圆半径) //范围参数2(无则填-1 圆形扫描 无填-1 扇形扫描扇形的角度值 直线扫描宽度距离 环形的外圆半径) //范围参数3(无则填-1 预留) //范围参数4(人数) private Vector2 InitCircleRange(Tab_SkillEx _skillExinfo, Tab_SkillTargetSelector selector, Vector2 vec, float rate = 0, bool isEnterRelex = false) { ControlEffect.gameObject.SetActive(false); return Vector2.zero; } private Vector2 InitSectorRange(Tab_SkillEx _skillExinfo, Tab_SkillTargetSelector selector, Vector2 vec, float rate = 0, bool isEnterRelex = false) { ControlEffect.gameObject.SetActive(true); var tex = SelectInner_Yellow; if (isEnterRelex) tex = SelectInner_Red; var dir = new Vector4(vec.x / 2 + 0.5f, vec.y / 2 + 0.5f, 1, 1); SetEffectSize(ControlEffect.transform, tex, _skillExinfo.Radius * 2); InitContrlo(tex, 1, 1, selector.GetRangParambyIndex(1), 0.2f, 0.002f, 0.005f, Color.red, dir, isEnterRelex); var point = Vector2.zero; point.x = Singleton.Instance.MainPlayer.Position.x + rate * _skillExinfo.Radius * vec.x; point.y = Singleton.Instance.MainPlayer.Position.z + rate * _skillExinfo.Radius * vec.y; return point; } private Vector2 InitLineRange(Tab_SkillEx _skillExinfo, Tab_SkillTargetSelector selector, Vector2 vec, float rate = 0, bool isEnterRelex = false) { ControlEffect.gameObject.SetActive(true); var tex = Line_Yellow; if (isEnterRelex) tex = Line_Red; float param1 = selector.GetRangParambyIndex(0); SetEffectSize(ControlEffect.transform, tex, _skillExinfo.Radius); InitContrlo(tex, 0, 0, 0, param1, 0, 0, Color.red, Vector4.zero, isEnterRelex); ControlRotation.localRotation = oldRotation; ControlEffect.transform.position = new Vector3(CircleEffect.transform.position.x, CircleEffect.transform.position.y, CircleEffect.transform.position.z + _skillExinfo.Radius / 2); var cross = Vector3.Cross(vec, new Vector3(0, 1, 0)); var angle = Vector2.Angle(new Vector2(0, 1), vec); if (cross.z < 0) angle = 360 - angle; ControlRotation.RotateAround(ControlRotation.position, new Vector3(0, 1, 0), angle); var point = Vector2.zero; point.x = Singleton.Instance.MainPlayer.Position.x + _skillExinfo.Radius * vec.x; point.y = Singleton.Instance.MainPlayer.Position.z + _skillExinfo.Radius * vec.y; return point; } private Vector2 InitRingRange(Tab_SkillEx _skillExinfo, Tab_SkillTargetSelector selector, Vector2 vec, float rate = 0, bool isEnterRelex = false) { ControlEffect.gameObject.SetActive(false); return Vector2.zero; } private Vector2 InitTripRange(Tab_SkillEx _skillExinfo, Tab_SkillTargetSelector selector, Vector2 vec, float rate = 0, bool isEnterRelex = false) { ControlEffect.gameObject.SetActive(true); var tex = isEnterRelex ? Trip_Red : Trip_Yellow; int param1 = selector.GetRangParambyIndex(0); param1 = param1 / 100; SetEffectSize(ControlEffect.transform, tex, param1 * 2); InitContrlo(tex, 0, 1, 0, param1, 0, 0, Color.red, Vector4.zero, isEnterRelex); ControlEffect.transform.localPosition = vec.InsertY(); return vec; } private void SetEffectSize(Transform texTransform, Texture tex, float size) { if (texTransform == null) return; if (size > 0) { var texHeigh = texTransform.localScale.y; var texWidth = texTransform.localScale.x; if (tex != null) { texHeigh = tex.height; texWidth = tex.width; } if (texHeigh > texWidth) texTransform.localScale = new Vector3(texWidth / texHeigh * size, size, 1); else texTransform.localScale = new Vector3(size, texHeigh / texWidth * size, 1); } else { texTransform.localScale = Vector3.one; } } private void SetCircleTex(bool isEnterRelex = false, float size = 0) { var tex = big_Yellow; if (isEnterRelex) tex = big_Red; CircleEffect.material.SetTexture("_ShadowTex", tex); //CircleEffect.material.SetInt("_UseChangeColor", isEnterRelex ? 0 : 1); SetEffectSize(CircleEffect.transform, tex, size); } private void InitContrlo(Texture tex, int type, float ratio, float Angle, float radiu, float linew1, float linew2, Color lineColor, Vector4 forword, bool isEnterRelex) { ControlEffect.material.SetTexture("_ShadowTex", tex); if (type > 0) ControlEffect.material.EnableKeyword("CLIP_BY_RANGE"); else ControlEffect.material.DisableKeyword("CLIP_BY_RANGE"); ControlEffect.material.SetFloat("_RangeAngle", Angle); ControlEffect.material.SetFloat("_RangeRadiu", radiu); ControlEffect.material.SetVector("_Forword", forword); ControlEffect.material.SetFloat("_LineW1", linew1); ControlEffect.material.SetFloat("_LineW2", linew2); ControlEffect.material.SetColor("_LineColor", lineColor); //ControlEffect.material.SetInt("_UseChangeColor", isEnterRelex ? 0 : 1); ControlRotation.localRotation = oldRotation; ControlEffect.transform.localPosition = Vector3.zero; } private Vector2 UpdateSectorRange(Vector2 vec, bool isEnterRelex) { var tex = SelectInner_Yellow; if (isEnterRelex) tex = SelectInner_Red; // 校正到方向 var dirVector2 = vec.normalized; var dir = new Vector4(dirVector2.x / 2 + 0.5f, dirVector2.y / 2 + 0.5f, 1, 1); ControlEffect.material.SetInt("_UseChangeColor", isEnterRelex ? 0 : 1); ControlEffect.material.SetTexture("_ShadowTex", tex); ControlEffect.material.SetVector("_Forword", dir); return vec; } private Vector2 UpdateTripRange(Vector2 vec, bool isEnterRelex) { var tex = isEnterRelex ? Trip_Red : Trip_Yellow; ControlEffect.material.SetTexture("_ShadowTex", tex); //ControlEffect.material.SetInt("_UseChangeColor", isEnterRelex ? 0 : 1); ControlEffect.transform.localPosition = vec.InsertY(); return vec; } private Vector2 UpdateLineRange(Vector2 vec, bool isEnterRelex) { var tex = Line_Yellow; if (isEnterRelex) tex = Line_Red; //ControlEffect.material.SetInt("_UseChangeColor", isEnterRelex ? 0 : 1); ControlEffect.material.SetTexture("_ShadowTex", tex); ControlRotation.localRotation = oldRotation; ControlRotation.rotation = Quaternion.LookRotation(vec.InsertY()); // //Vector3 cross = Vector3.Cross(vec, new Vector3(0, 1, 0)); //float angle = Vector2.Angle(new Vector2(0, 1), vec); //if (cross.z < 0) // angle = 360 - angle; //ControlRotation.RotateAround(ControlRotation.position, new Vector3(0, 1, 0), angle); // // // //Vector2 point = Vector2.zero; //point.x = Singleton.Instance.MainPlayer.Position.x + radiu * vec.x; //point.y = Singleton.Instance.MainPlayer.Position.z + radiu * vec.y; return vec; } private Vector2 UpdateCircleRange(Vector2 vec, bool isEnterRelex) { return Vector2.zero; } private Vector2 UpdateRingRange(Vector2 vec, bool isEnterRelex) { return Vector2.zero; } //Vector2 WorldToCamera(Vector2 dirVec) //{ // Vector3 forward = Camera.main.transform.TransformDirection(Vector3.forward); // forward.y = 0; // forward = forward.normalized; // Vector3 right = new Vector3(forward.z, 0, -forward.x); // // var targetDirection = dirVec.x * right + dirVec.y * forward; // targetDirection = targetDirection.normalized; // dirVec.x = targetDirection.x; // dirVec.y = targetDirection.z; // return dirVec; //} public Vector2 UpdatePos(Vector2 vec, bool isEnterRelex) { if (currentSkill != null) { var selector = TableManager.GetSkillTargetSelectorByID(currentSkill.GetSelectorIdbyIndex(0)); var type = GetSkillType(currentSkill, selector); if (type == null) { gameObject.SetActive(false); return Vector2.zero; } else { SetCircleTex(isEnterRelex, currentSkill.Radius * 2); switch (type) { case 1: return UpdateCircleRange(vec, isEnterRelex); case 2: return UpdateSectorRange(vec, isEnterRelex); case 3: return UpdateLineRange(vec, isEnterRelex); case 4: return UpdateRingRange(vec, isEnterRelex); case 5: return UpdateTripRange(vec, isEnterRelex); default: return Vector2.zero; } } } else return Vector2.zero; } // 目测-1等负数在switch中出现,因此只能用null表示不可使用的类型 private int? GetSkillType(Tab_SkillEx skillEx, Tab_SkillTargetSelector selector) { int? type; if (selector != null) { if (skillEx.IsTargetGround()) { type = selector.RangType; if (selector.RangCenter == 1) type = 5; } else { type = 1; } } else type = null; return type; } }