首页 文章

我的Unity角色需要什么代码才能正确射击子弹?

提问于
浏览
0

我不是编程的新手,但我是C#的新手 . 我在Python,Java和HTML方面经验丰富 . 我的游戏是2D我有一个游戏,我的角色目前必须触摸敌人来杀死它 . 现在我添加了射击子弹杀死敌人的代码 . 如果按下空格键,我也希望弹射子弹 . 这个角色应该是向两个方向射击的子弹 . 我从我的教授给我的一个例子中获取了我的代码,这个例子最初是Javascript,我将它转换为C# . Unity不再支持Javascript . 他给我的示例代码基本上是一个火箭射击,因为我点击了许多子弹(点击鼠标射击子弹)来消灭敌人,但是那个例子中的火箭不会移动 . 在我的游戏中,角色移动,因此子弹必须获得角色的位置 . 获得角色位置和正确射击子弹的正确代码是什么?

我用我当前的代码测试了我的游戏 . 子弹从外面吐出(从我背景壁纸的底部[在底部中间拍到]到壁纸下面一点点) . 甚至不是来自角色...另外,我将Hit类脚本添加到Unity中的Bullet类别 .

完整的相机控制器(这里没有问题)

using UnityEngine;
using System.Collections;

public class CompleteCameraController : MonoBehaviour {

    public GameObject player;       //Public variable to store a reference to the player game object


    private Vector3 offset;         //Private variable to store the offset distance between the player and camera

    // Use this for initialization
    void Start () 
    {
        //Calculate and store the offset value by getting the distance between the player's position and camera's position.
        offset = transform.position - player.transform.position;
    }

    // LateUpdate is called after Update each frame
    void LateUpdate () 
    {
        // Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
        transform.position = player.transform.position + offset;
    }
}

完整的播放器控件类(如果您阅读代码中的“BULLET CODE”中的注释,那是我在游戏中为子弹放置的新代码 .

using UnityEngine;
using System.Collections;

//Adding this allows us to access members of the UI namespace including Text.
using UnityEngine.UI;

public class CompletePlayerController : MonoBehaviour
{

    public float speed;             //Floating point variable to store the player's movement speed.
    public Text countText;          //Store a reference to the UI Text component which will display the number of pickups collected.
    public Text winText;            //Store a reference to the UI Text component which will display the 'You win' message.

    private Rigidbody2D rb2d;       //Store a reference to the Rigidbody2D component required to use 2D Physics.
    private int count;              //Integer to store the number of pickups collected so far.
    Rigidbody2D bullet;
    float speed2 = 30f; //BULLET CODE



    // Use this for initialization
    void Start()
    {
        //Get and store a reference to the Rigidbody2D component so that we can access it.
        rb2d = GetComponent<Rigidbody2D> ();

        //Initialize count to zero.
        count = 0;

        //Initialze winText to a blank string since we haven't won yet at beginning.
        winText.text = "";

        //Call our SetCountText function which will update the text with the current value for count.
        SetCountText ();
    }

    //FixedUpdate is called at a fixed interval and is independent of frame rate. Put physics code here.
    void FixedUpdate()
    {
        //Store the current horizontal input in the float moveHorizontal.
        float moveHorizontal = Input.GetAxis ("Horizontal");

        //Store the current vertical input in the float moveVertical.
        float moveVertical = Input.GetAxis ("Vertical");

        Rigidbody2D bulletInstance; //BULLET CODE

        //Use the two store floats to create a new Vector2 variable movement.
        Vector2 movement = new Vector2 (moveHorizontal, moveVertical);

        //Call the AddForce function of our Rigidbody2D rb2d supplying movement multiplied by speed to move our player.
         rb2d.AddForce (movement * speed);

         if(Input.GetKeyDown(KeyCode.Space)&& Hit.hit == false) //BULLET CODE IN HERE
        {
            // ... instantiate the bullet facing right and set it's velocity to the right. 
            bulletInstance = Instantiate(bullet, transform.position, Quaternion.Euler(new Vector3(0,0,0)));
            bulletInstance.velocity = new Vector2(speed2, 0);
            bulletInstance.name = "Bullet";
        }







    }




    //OnTriggerEnter2D is called whenever this object overlaps with a trigger collider.
    void OnTriggerEnter2D(Collider2D other) 
    {
        //Check the provided Collider2D parameter other to see if it is tagged "PickUp", if it is...
        if (other.gameObject.CompareTag ("PickUp")) 
        {
            //... then set the other object we just collided with to inactive.
            other.gameObject.SetActive(false);

            transform.localScale += new Vector3(0.1f, 0.1f, 0);

            //Add one to the current value of our count variable.
            count = count + 1;

            //Update the currently displayed count by calling the SetCountText function.
            SetCountText ();
        }


    }

    //This function updates the text displaying the number of objects we've collected and displays our victory message if we've collected all of them.
    void SetCountText()
    {
        //Set the text property of our our countText object to "Count: " followed by the number stored in our count variable.
        countText.text = "Count: " + count.ToString ();

        //Check if we've collected all 12 pickups. If we have...
        if (count >= 12)
            //... then set the text property of our winText object to "You win!"
            winText.text = "You win!";
    }
}

命中代码 . 此类中的所有代码都是针对项目符号生成的 .

using UnityEngine;
using System.Collections;

public class Hit : MonoBehaviour 
{


    GameObject[] gameObjects;
    public static bool hit = false;

    void  Removal ()
    {

    gameObjects =  GameObject.FindGameObjectsWithTag("Bullet");

    for(var i= 0 ; i < gameObjects.Length ; i ++)
        Destroy(gameObjects[i]);
    }

    void  OnCollisionEnter2D ( Collision2D other  )
    {
        if(other.gameObject.name=="Bullet")
        {
            Removal();
            Destroy(gameObject);
            hit = true;

        }
    }
}

2 回答

  • 0

    我看到你写的代码有几个问题 . 正如@Kyle Delaney建议的那样,我也强烈建议您查看Unity Learn网站,并在完成之前先阅读几个教程 . 我已经强调了下面的一些问题可能有助于解决您的问题,但您可以从一开始就改变您的方法,从而避免许多这些问题 . 见下文 .

    在您的相机控制器类中,为什么不公开偏移,以便您可以在检查器中自己设置>

    在Player控制器类中:

    改变:

    if (Input.GetKeyDown(KeyCode.Space)) //Shoot bullet
    {
        // ... instantiate the bullet facing right and set it's velocity to the right. 
        Rigidbody2D bulletRB = Instantiate(bullet, transform.position, transform.rotation);
        bulletRB.AddForce(new Vector2(speed2,0), ForceMode2D.Impulse);
    }
    

    单击一下,这将实例化子弹预制件并设置其变换以复制播放器的位置和旋转 . 然后它向右边添加一个力 . 您应该避免使用刚体手动设置速度,这可能会导致不必要的行为 . 请改用Addforce / addTorque方法 . ForceMode说要忽略它的质量并设置它的速度 .

    然后删除你的Hit类,并替换为你拖到子弹预制件上的这个Bullet类 . 你的玩家不应该负责检查子弹击中 . 这是子弹的工作 . 玩家只是发射子弹,然后子弹做子弹做的 . 这只是检查子弹是否击中任何东西,如果是这样就会摧毁它 . 如果你愿意,你可以把它变得更复杂 . 我建议使用图层来确定子弹检查碰撞的层 . 你可能不希望子弹摧毁你的地形 . 而你绝对不希望子弹摧毁玩家本身!

    public class Bullet : MonoBehaviour
    {
    
        private void OnCollisionEnter2D(Collision2D collision)
        {
            Destroy(collision.gameObject);
            Destroy(this.gameObject);
        }
    
    }
    

    此外,您不需要设置子弹的名称,因为您的预制子弹应该已经命名为“bullet” .

    我希望这能让你开始朝着正确的方向前进 . 但根据您的代码,我强烈建议您在继续任何项目之前完成教程 . 制作它们的团结人员非常有帮助,教程开始非常简单但快速变得非常复杂,所以你实际上学到了很多东西!

  • 1

    也许问题与玩家的父变换有关 . 您可以尝试这样的方法来确保子弹有正确的父级:

    bulletInstance = Instantiate(bullet);
    bulletInstance.transform.parent = transform.parent;
    bulletInstance.transform.position = transform.position;
    bulletInstance.velocity = new Vector2(speed2, 0);
    bulletInstance.name = "Bullet";
    

    如果这不起作用,可能值得检查玩家的矩形变换以查看锚点和枢轴的位置 . 也许球员的实际“位置”坐标不在你认为的位置 .

    你做过太空射击教程吗?它有segment about shooting bullets .

相关问题