679 lines
17 KiB
Plaintext
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();
|
|
}
|
|
}
|