326 lines
12 KiB
C#
326 lines
12 KiB
C#
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<ObjManager>.Instance.MainPlayer == null)
|
||
return Vector2.zero;
|
||
var x = Singleton<ObjManager>.Instance.MainPlayer.transform.position.x;
|
||
var y = Singleton<ObjManager>.Instance.MainPlayer.transform.position.y + 0.5f;
|
||
var z = Singleton<ObjManager>.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<ObjManager>.Instance.MainPlayer.Position.x + rate * _skillExinfo.Radius * vec.x;
|
||
point.y = Singleton<ObjManager>.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<ObjManager>.Instance.MainPlayer.Position.x + _skillExinfo.Radius * vec.x;
|
||
point.y = Singleton<ObjManager>.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<ObjManager>.Instance.MainPlayer.Position.x + radiu * vec.x;
|
||
//point.y = Singleton<ObjManager>.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;
|
||
}
|
||
} |