WXMC/.svn/pristine/a3/a3387533ce9357051ce823bc9a231ea9da7f7709.svn-base
2024-12-04 16:18:46 +08:00

679 lines
17 KiB
Plaintext

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Sirenix.OdinInspector;
[System.Serializable]
public struct ProjectileDirection
{
public bool FromContext;
[ShowIf("FromContext", true)]
public ShootDataDirections Direction;
[ShowIf("@!FromContext")]
public Vector2 Constant;
public bool Reverse;
public Vector2 GetDirection(in ShootData shootData, Vector2 position)
{
Vector2 result;
if (FromContext)
{
result = shootData.GetDirection(Direction, position).Value;
}
else
{
result = Constant.normalized;
}
float sign = Reverse ? -1 : 1;
return result * sign;
}
}
public class PHomeProjectileMover : MonoBehaviour
{
private PHomeProjectileBase m_projectile;
public PHomeProjectileBase Projectile
{
get
{
if (m_projectile == null)
{
m_projectile = GetComponent<PHomeProjectileBase>();
}
return m_projectile;
}
}
[SerializeField]
protected MoveType m_moveType;
private Rigidbody2D m_rigidBody;
protected Rigidbody2D PhysicsBody
{
get
{
if (m_rigidBody == null)
{
m_rigidBody = GetComponent<Rigidbody2D>();
}
return m_rigidBody;
}
}
#region Dest Velocity
[SerializeField]
private bool m_enableDestVelocity;
private bool UseDestVelocity()
{
return m_enableDestVelocity;
}
protected PhysicsMovement2D m_movement;
protected PhysicsMovement2D PhysicsMovement
{
get
{
if (m_movement == null)
{
m_movement = GetComponent<PhysicsMovement2D>();
}
return m_movement;
}
}
[SerializeField]
[ShowIf("UseDestVelocity")]
protected MoveCalType m_moveCalType;
private bool UseLinearDestVelocity()
{
return UseDestVelocity() && m_moveCalType == MoveCalType.Linear;
}
[SerializeField]
[ShowIf("UseLinearDestVelocity")]
protected float m_speed;
public float Speed
{
get
{
return m_speed;
}
set
{
m_speed = value;
}
}
[SerializeField]
[ShowIf("UseLinearDestVelocity")]
private ProjectileDirection m_linearDirection;
#endregion
#region Physics
[SerializeField]
[ShowIf("m_moveType", MoveType.PhysicsMovement2D)]
private bool m_enableStartVelocity;
private bool UseStartSpeed()
{
return m_enableStartVelocity && m_moveType == MoveType.PhysicsMovement2D;
}
[SerializeField]
[ShowIf("UseStartSpeed")]
private float m_startSpeed;
[SerializeField]
[ShowIf("UseStartSpeed")]
private ProjectileDirection m_startDirection;
[SerializeField]
[ShowIf("m_moveType", MoveType.PhysicsMovement2D)]
private bool m_enableGravity;
private bool UseGravity()
{
return m_enableGravity && m_moveType == MoveType.PhysicsMovement2D;
}
[SerializeField]
[ShowIf("UseGravity")]
private float m_gravityScale;
[SerializeField]
[ShowIf("UseGravity")]
private ProjectileDirection m_gravityDirection;
#endregion
[BoxGroup("Debug")]
[SerializeField]
protected bool m_moveFinish;
public bool MoveFinish
{
get
{
return m_moveFinish;
}
set
{
m_moveFinish = value;
}
}
[SerializeField]
protected bool m_bounceOffScreen;
public bool BounceOffScreen
{
get
{
return m_bounceOffScreen;
}
set
{
m_bounceOffScreen = value;
}
}
[SerializeField]
protected bool m_return;
public bool Return
{
get
{
return m_return;
}
}
[SerializeField]
protected bool m_destroyOffScreen;
public bool DestroyOffScreen
{
get
{
return m_destroyOffScreen;
}
}
[BoxGroup("Debug")]
[SerializeField]
protected Vector3 m_destVelocity;
public Vector3 DestVelocity
{
get
{
return m_destVelocity;
}
set
{
m_destVelocity = value;
}
}
private Vector2? m_lastDestVelocity;
public Vector3 Velocity
{
get
{
switch (m_moveType)
{
case MoveType.PhysicsMovement2D:
return PhysicsBody.velocity;
case MoveType.PositionMovement:
return m_destVelocity;
default:
break;
}
return default;
}
}
protected ShootData m_shootData;
private Action m_moveFinishAc;
private Vector2? CalcDestVelocity()
{
Vector2? direction = default;
switch (m_moveCalType)
{
case MoveCalType.Linear:
{
direction = m_linearDirection.GetDirection(m_shootData, transform.position);
}
break;
case MoveCalType.LaserWave:
break;
case MoveCalType.CircleMove:
break;
case MoveCalType.BezierCurveMove:
break;
case MoveCalType.None:
break;
}
return direction * m_speed;
}
public virtual void Init(in ShootData shootData, Action movefinishAc)
{
m_shootData = shootData;
m_moveFinishAc = movefinishAc;
Init_ApplyStartSpeed();
}
private void Init_ApplyStartSpeed()
{
if (!m_enableStartVelocity)
{
return;
}
switch (m_moveType)
{
case MoveType.PhysicsMovement2D:
{
PhysicsBody.velocity = m_startDirection.GetDirection(m_shootData, transform.position) * m_startSpeed;
}
break;
case MoveType.PositionMovement:
break;
}
}
private void TryFinishMove()
{
if (m_moveFinish)
{
return;
}
Vector2? targetPoint = m_shootData.GetTargetPoint();
if (targetPoint == null)
{
return;
}
if (Vector2.Distance(targetPoint.Value, transform.position) <= 0.05f)
{
FinishMoving();
}
}
protected virtual void Update_Movement()
{
TryFinishMove();
if (m_enableDestVelocity)
{
Vector2? destVel = CalcDestVelocity();
if (destVel != null)
{
m_lastDestVelocity = destVel;
}
else
{
destVel = m_lastDestVelocity;
}
destVel = destVel ?? Vector2.zero;
switch (m_moveType)
{
case MoveType.PhysicsMovement2D:
PhysicsMovement.DestVelocity = destVel.Value;
break;
case MoveType.PositionMovement:
//PositionMovement();
Projectile.ProjectilePosition += destVel.Value * Time.deltaTime;
break;
default:
break;
}
}
if (m_enableGravity)
{
PhysicsBody.AddForce(m_gravityDirection.GetDirection(m_shootData, transform.position) * m_gravityScale);
}
}
void Update_Pos()
{
Vector2 ScreenPos = Camera.main.WorldToScreenPoint(transform.position);
if (DestroyOffScreen)
{
if (ScreenPos.x > Screen.width)
{
Destroy(gameObject);
}
if (ScreenPos.x < 0)
{
Destroy(gameObject);
}
if (ScreenPos.y > Screen.height)
{
Destroy(gameObject);
}
if (ScreenPos.y <= 0)
{
Destroy(gameObject);
}
}
}
private void PositionMovement()
{
switch (m_moveCalType)
{
case MoveCalType.Linear:
LinearToEndPositionMove();
break;
case MoveCalType.LaserWave:
LaserWaveMove();
break;
case MoveCalType.CircleMove:
CircleMove();
break;
case MoveCalType.BezierCurveMove:
BezierCurveMove();
break;
default:
break;
}
}
Vector2 midPos = Vector2.zero;
private float t = 0f;
[BoxGroup("Debug")]
public Vector2 nextPos;
void BezierCurveMove()
{
if(MoveFinish){return;}
if(minPos == Vector2.zero)
{
CalMidPos();
}
if (t < 1f)
{
t += Time.deltaTime * Speed;
t = t > 1 ? 1 : t;
Vector2 position = GetCurvePoint(t, m_shootData.StartPoint, midPos, m_shootData.EndPoint.Value);
float nextT = t+0.01f;
nextPos = GetCurvePoint(nextT>1?1:nextT, m_shootData.StartPoint, midPos, m_shootData.EndPoint.Value) - position;
if(transform!=null && position.x!=float.NaN)
{
transform.position = position;
}
}
else
{
Projectile.ProjectilePosition = m_shootData.EndPoint.Value;
if (m_moveFinishAc != null) m_moveFinishAc();
//m_moveFinished = true;
}
}
public static Vector2 GetCurvePoint(float t,Vector2 _point0, Vector2 _point1, Vector2 _point2)
{
t = Mathf.Clamp(t, 0.0f, 1.0f);
// Debug.Log("~~t:"+t+" "+_point0+ " "+_point1+" "+_point2);
float x = ((1 - t) * (1 - t)) * _point0.x + 2 * t * (1 - t) * _point1.x + t * t * _point2.x;
float y = ((1 - t) * (1 - t)) * _point0.y + 2 * t * (1 - t) * _point1.y + t * t * _point2.y;
//float z = ((1 - t) * (1 - t)) * _point0.z + 2 * t * (1 - t) * _point1.z + t * t * _point2.z;
Vector2 pos = new Vector2(x, y);
return pos;
}
void CalMidPos()
{
// 计算中点
Vector2 midPoint = (m_shootData.StartPoint + m_shootData.EndPoint.Value) / 2;
// 计算起点到终点的方向
Vector2 direction = m_shootData.EndPoint.Value - m_shootData.StartPoint;
// 计算垂直方向(法线方向)
Vector3 perpendicular = new Vector3(-direction.y, direction.x).normalized;
// 计算控制点
//if (m_shootData.ProjectileIndex % 2 == 0)
//{
// midPos = midPoint + (perpendicular * 0.3f * direction.magnitude) ;
//}
//else
//{
// midPos = midPoint - (perpendicular * 0.7f * direction.magnitude);
//}
}
float currAngle = -1;
void CircleMove()
{
//if (currAngle == -1)
//{
// currAngle = m_shootData.Angle;
//}
//currAngle += Time.deltaTime * Speed;
//if (currAngle > 360) { currAngle = currAngle % 360; }
//float x = m_shootData.Radius * Mathf.Cos(currAngle * Mathf.Deg2Rad);
//float y = m_shootData.Radius * Mathf.Sin(currAngle * Mathf.Deg2Rad);
//transform.position = m_shootData.TargetUnit.transform.position + new Vector3(x, y, 0);
}
bool projectileReturn;
float posX;
float posY;
Vector3 projectilePos;
void LaserWaveMove()
{
//if (m_shootData.ProjectileIndex % 2 == 0)
//{
// if (projectileReturn)
// {
// posX += Time.deltaTime * Speed;
// }
// else
// {
// posX -= Time.deltaTime * Speed;
// }
// if (posX <= -1)
// {
// projectileReturn = true;
// }
// else if (posX >= 0)
// {
// projectileReturn = false;
// }
//}
//else
//{
// if (projectileReturn)
// {
// posX -= Time.deltaTime * Speed;
// }
// else
// {
// posX += Time.deltaTime * Speed;
// }
// if (posX > 1)
// {
// projectileReturn = true;
// }
// else if (posX <= 0)
// {
// projectileReturn = false;
// }
//}
//if (m_shootData.ProjectileIndex < 2)
//{
// posY += Time.deltaTime * Speed / 2;
//}
//else
//{
// posY -= Time.deltaTime * Speed / 2;
//}
//if (posY > 3 || posY < -3)
//{
// Destroy(gameObject);
//}
//projectilePos.x = posX;
//projectilePos.y = posY;
//transform.position = m_shootData.StartPoint + projectilePos;
}
Vector2 maxPos;
Vector2 minPos;
void LinearDirectionMove()
{
if (m_destVelocity == Vector3.zero)
{
m_destVelocity = (m_shootData.EndPoint.Value - m_shootData.StartPoint).normalized;
}
Vector2 ScreenPos = Camera.main.WorldToScreenPoint(transform.position);
if (BounceOffScreen)
{
if (ScreenPos.x >= Screen.width && m_destVelocity.x > 0)
{
m_destVelocity.x = -m_destVelocity.x;
}
if (ScreenPos.x <= 0 && m_destVelocity.x < 0)
{
m_destVelocity.x = -m_destVelocity.x;
}
if (ScreenPos.y >= Screen.height && m_destVelocity.y > 0)
{
m_destVelocity.y = -m_destVelocity.y;
}
if (ScreenPos.y <= 0 && m_destVelocity.y < 0)
{
m_destVelocity.y = -m_destVelocity.y;
}
// maxPos = PHomeGameMode.main.PlayerUnit.GetPosMax();
// minPos = PHomeGameMode.main.PlayerUnit.GetPosMin();
// if (transform.position.x >= maxPos.x && m_destVelocity.x > 0)
// {
// m_destVelocity.x = -m_destVelocity.x;
// }
// if (transform.position.x <= minPos.x && m_destVelocity.x < 0)
// {
// m_destVelocity.x = -m_destVelocity.x;
// }
// if (transform.position.y >= maxPos.y && m_destVelocity.y > 0)
// {
// m_destVelocity.y = -m_destVelocity.y;
// }
// if (transform.position.y <= minPos.y && m_destVelocity.y < 0)
// {
// m_destVelocity.y = -m_destVelocity.y;
// }
}
finalVel = m_destVelocity * Speed;
transform.position = transform.position + finalVel * Time.deltaTime;
}
public void LinearToTargetMove()
{
if (m_shootData.TargetUnit == null)
{
//目标丢失事件
TargetLos();
}
else
{
m_destVelocity = m_shootData.TargetUnit.transform.position - transform.position;
//m_preVelocity = m_destVelocity.normalized;
PhysicsMovement.DestVelocity = m_destVelocity.normalized * Speed;
}
}
public void Rebound(Transform collider)
{
m_destVelocity = transform.position - collider.transform.position;
}
Vector3 finalVel = Vector3.zero;
//bool m_moveFinished;
bool m_returnSpeed;
void LinearToEndPositionMove()
{
// TODO iii
//if (m_moveFinished) return;
//if (m_destVelocity == Vector3.zero)
//{
// m_destVelocity = (m_shootData.EndPoint.Value - m_shootData.StartPoint).normalized;
//}
//finalVel = m_destVelocity * Speed;
//transform.position = transform.position + finalVel * Time.deltaTime;
//if (Return && m_returnSpeed) return;
//if ((transform.position - m_shootData.StartPoint).magnitude >= (m_shootData.EndPoint - m_shootData.StartPoint).magnitude)
//{
// transform.position = m_shootData.EndPoint;
// if (m_moveFinishAc != null) m_moveFinishAc();
// if (Return)
// {
// m_returnSpeed = true;
// m_destVelocity = m_shootData.StartPoint - m_shootData.EndPoint;
// }
// else
// {
// m_moveFinished = true;
// }
//}
}
void TargetLos()
{
//m_movement.DestVelocity = m_preVelocity * Speed;
}
void ArriveTarget()
{
if (m_destVelocity.magnitude < 0.01f)
{
FinishMoving();
}
}
void FinishMoving()
{
if (m_moveFinish)
{
return;
}
MoveFinish = true;
Projectile.OnMovingFinished();
}
protected virtual void Update()
{
Update_Movement();
Update_Pos();
}
}