实例化朝向玩家位置的子弹



在输入左键单击(fire1(上,弹丸从ProjectIlpawn位置产生。在右键单击(FIRE2(上,我想将弹丸拍摄"反向",然后从ProjectIlespawntwo位置开始,然后返回到最初的ProjectilSpaink位置。目前,它向前射击,但我希望弹丸能够将其产生到确切的位置。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerWeapon : MonoBehaviour 
{
    public GameObject projectilePrefab;
    public GameObject projectileTwoPrefab;
    public Transform projectileSpawn;
    public Transform projectileSpawnTwo;
    public float projectileSpeed = 30;  
    void Update () 
    {
        if (Input.GetButtonDown("Fire1")) 
        {
            Fire();
        }
        if (Input.GetButtonDown("Fire2")) 
        {
            Fire2();
        }
    }
    private void Fire() 
    {
        GameObject projectile = Instantiate(projectilePrefab);
        Physics.IgnoreCollision(projectile.GetComponent<Collider>(),
                                projectileSpawn.parent.GetComponent<Collider>()); 
        projectile.transform.position = projectileSpawn.position;
        var rot = projectile.transform.rotation.eulerAngles;
        projectile.transform.rotation = Quaternion.Euler(rot.x, transform.eulerAngles.y, rot.z);
        projectile.GetComponent<Rigidbody>().AddForce(projectileSpawn.forward * projectileSpeed, ForceMode.Impulse);       
    }
    private void Fire2()
    {
        GameObject projectile = Instantiate(projectileTwoPrefab);
        Physics.IgnoreCollision(projectile.GetComponent<Collider>(),
                                projectileSpawnTwo.parent.GetComponent<Collider>()); 
        projectile.transform.position = projectileSpawnTwo.position;
        var rot = projectile.transform.rotation.eulerAngles;
        projectile.transform.rotation = Quaternion.Euler(rot.x, transform.eulerAngles.y, rot.z);
        projectile.GetComponent<Rigidbody>().AddForce(projectileSpawnTwo.forward * projectileSpeed, ForceMode.Impulse);
    }
}

,因为这两种方法都非常相似,您可以稍微概括您的方法

private Collider projectileSpawnParentCollider;
privtae enum FireType
{
    One,
    Two
}
private void Awake()
{
  // this hould probably done only once to be more efficient
  projectileSpawnParentCollider = projectileSpawn.parent.GetComponent<Collider>();
}
private void Update()
{
    if (Input.GetButtonDown("Fire1")) 
    {
        Fire(FireType.One);
    }
    if (Input.GetButtonDown("Fire2")) 
    {
        Fire(FireType.Two);
    }
}
private void Fire(FireType fireType) 
{
    var position = fireType == FireType.One ? projectileSpawn.position : projectileSpawnTwo.position;
    var rot = projectile.transform.rotation.eulerAngles;
    var rotation = Quaternion.Euler(rot.x, transform.eulerAngles.y, rot.z);
    // pass the position and rotation alraedy
    GameObject projectile = Instantiate(projectilePrefab, position, rotation);
    Physics.IgnoreCollision(projectile.GetComponent<Collider>(), projectileSpawnParentCollider);

    var forceDirection = fireType == FireType.One ? projectileSpawn.forward : (projectileSpawn.position - projectileSpawnTwo.position).normalized;
    projectile.GetComponent<Rigidbody>().AddForce(forceDirection * projectileSpeed, ForceMode.Impulse);
}

projectileSpawn.position - projectileSpawnTwo.position

返回一个指向从projectileSpawnTwo.positionprojectileSpawn.position的向量。使用normalized返回具有相同方向但使用magnitude = 1的向量。


但是,请注意,只有在第二张拍摄后玩家没有移动时,这才能做到这一点。如果玩家可以移动,您可能应该宁愿实现另一个组件以使子弹对象实际上遵循玩家位置。

您可以使用Quaternion.LookRotationRigidbody.MoveRotation来编写单独的组件,例如

public class FollowPlayer : MonoBehaviour
{
    public Transform PlayerTransform;
    public RigidBody rigiBody;
    public speed;
    private void Awake()
    {
       rigidBody = GetComponent<RigidBody>();
    }
    private void LateUpdate()
    {
        if(!PlayerTrasnform) return;
        var rotation = Quaternion.LookRotation(PlayerTransform.position - transform.position, Vector3.up);
        rigidBody.MoveRotation(rotation);
        rigidBody.velocity = (PlayerTransform.position - transform.position).normalized * speed;
    }
}

,在您的脚本中添加组件,例如

private void Fire(FireType fireType) 
{
    var position = fireType == FireType.One ? projectileSpawn.position : projectileSpawnTwo.position;
    var rot = projectile.transform.rotation.eulerAngles;
    var rotation = Quaternion.Euler(rot.x, transform.eulerAngles.y, rot.z);
    // pass the position and rotation alraedy
    GameObject projectile = Instantiate(projectilePrefab, position, rotation);
    Physics.IgnoreCollision(projectile.GetComponent<Collider>(), projectileSpawnParentCollider);
    if(fireType == FireType.One)
    {
        projectile.GetComponent<Rigidbody>().AddForce(projectileSpawn.forward * projectileSpeed, ForceMode.Impulse);
    }
    else
    {
        var follow = projectile.AddComponent<FollowPlayer>();
        follow.speed = projectileSpeed;
        follow.PlayerTransform = YourPlayerTransform; // or probably projectileSpawn
    }
}

注意:在智能手机上打字,所以没有任何保证,但我希望这个想法变得清晰。

最新更新