将子弹实例化为玩家位置

时间:2019-05-23 12:15:33

标签: c# unity3d

在输入左键单击(Fire1)时,弹丸从projectileSpawn位置生成。右键单击(Fire2),我要使射弹“反向”射击,并从projectileSpawnTwo位置开始,再返回到初始的projectileSpawn位置。目前它向前方射击,但我希望射弹重生回精确的位置。

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);
    }
}

1 个答案:

答案 0 :(得分:2)

由于这两种方法都非常相似,因此可以概括一下您的方法

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);
}

The

projectileSpawn.position - projectileSpawnTwo.position

返回从projectileSpawnTwo.position指向projectileSpawn.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
    }
}

注意:请在智能手机上输入内容,因此无需任何担保,但我希望这个主意会变得清晰起来。