Files
JJBB/Assets/Project/Script/SkillCircleProjector.cs

326 lines
12 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
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;
}
}