В ProjectileSpawner
добавьте поле LayerMask
, чтобы отфильтровать недопустимые столкновения (установите его в инспекторе) для неходящего снаряда.Вы установите это в инспекторе, чтобы неходящие снаряды сталкивались с нужными слоями:
public LayerMask collisionLayers;
В Insert
найдите луч, идущий от центра экрана, и используйте его и LayerMask
в качестве параметра для SetTarget
:
public void Insert(GameObject target)
{
if (projectile) return;
Ray centerRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2, Screen.height/2, 0f));
projectile = Instantiate(projectileInsert, transform.position, Quaternion.identity);
ProjectileScript projectileScript = projectile.GetComponent<ProjectileScript>();
projectileScript.SetTarget(centerRay, collisionLayers);
projectileScript.speed = projectileSpeed;
// Physics.IgnoreCollision(projectile.GetComponent<Collider>(),
// projectileSpawn.parent.GetComponent<Collider>());
}
public void Extract(GameObject target)
{
if (projectile) return;
projectile = Instantiate(projectileExtract, target.transform.position, Quaternion.identity);
ProjectileScript projectileScript = projectile.GetComponent<ProjectileScript>();
projectileScript.SetTarget(gameObject);
projectileScript.speed = projectileSpeed;
// Physics.IgnoreCollision(projectile.GetComponent<Collider>(),
// projectileSpawn.parent.GetComponent<Collider>());
}
Затем в ProjectileScript
добавьте поле bool
, чтобы запомнить, находится ли снаряд на объекте gameObject или если он следует за лучом, a *Поле 1014 * для запоминания такого луча и поле LayerMask
для запоминания того, с чем сталкиваться:
public bool isHoming;
public Ray TargetRay
public LayerMask collisionLayers;
Затем в public void SetTarget(GameObject target)
установите для bool
значение true
:
public void SetTarget(GameObject target)
{
this.Target = target.transform;
isHoming = true;
}
И создайте новый public void SetTarget(Ray shootRay)
, который запоминает Ray
и LayerMask
и устанавливает bool
в false
:
public void SetTarget(Ray shootRay, LayerMask collisionLayers)
{
this.TargetRay = shootRay;
this.collisionLayers = collisionLayers;
isHoming = false;
}
Кроме того, в ProjectileScript
Вам нужно будет изменить метод FixedUpdate
, чтобы проверить, является ли bool истинным, и если это так, то сделать то же самое, что и раньше.В противном случае, двигайтесь вдоль луча и уничтожайте его, если он путешествует слишком далеко:
public float maxDistanceBeforeDestroy = 100f;
...
void FixedUpdate()
{
if (isHoming)
{
// _rigidbody.AddForce((Target.position - transform.position).normalized, ForceMode.Impulse);
Collider targetCollider = Target.GetComponent<Collider>();
Vector3 targetDirection;
if (targetCollider)
targetDirection = targetCollider.ClosestPoint(transform.position) - transform.position;
else
targetDirection = Target.position - transform.position;
_rigidbody.velocity = targetDirection.normalized * speed;
if (Vector3.Distance(transform.position, Target.position) < 1.0f)
{
//make the explosion
GameObject ThisExplosion = Instantiate(Explosion, gameObject.transform.position, gameObject.transform.rotation) as GameObject;
//destory the projectile
Destroy(gameObject);
}
}
else
{
_rigidbody.velocity = TargetRay.direction.normalized * speed;
// Check if it has traveled too far
if ((transform.position - TargetRay.origin).magnitude > maxDistanceBeforeDestroy )
{
Destroy(gameObject);
}
}
}
Затем добавьте метод OnCollisionEnter
, который ничего не делает, если снаряд находится в исходном положении.Но если это не так, он проверяет, совпадает ли столкновение с LayerMask
, и если это так, то делает взрыв и уничтожает снаряд:
void OnCollisionEnter(Collision other)
{
if (isHoming)
{
return;
}
if( && ((1<<other.gameObject.layer) & collisionLayers) != 0)
{
//make the explosion
GameObject ThisExplosion = Instantiate(Explosion,
gameObject.transform.position,
gameObject.transform.rotation) as GameObject;
//destroy the projectile
Destroy(gameObject);
}
}