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;
|
|||
|
}
|
|||
|
}
|