簡體   English   中英

我的Unity角色正確發射子彈需要什么代碼?

[英]What code do I need for my Unity character to shoot the bullet correctly?

我不是編程新手,但是我是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;

        }
    }
}

我看到您編寫的代碼有幾個問題。 正如@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類替換,將其拖動到bullet預制件上。 您的播放器不應該負責檢查子彈命中。 那是子彈的工作。 玩家只是發射子彈,然后子彈做子彈。 這只是檢查子彈是否擊中了任何東西,如果是的話,它將把它摧毀。 如果需要,可以使此操作更加復雜。 我建議使用圖層來確定項目符號檢查與哪些圖層碰撞。 您可能不希望子彈破壞您的地形。 而且您絕對不希望子彈摧毀玩家本身!

public class Bullet : MonoBehaviour
{

    private void OnCollisionEnter2D(Collision2D collision)
    {
        Destroy(collision.gameObject);
        Destroy(this.gameObject);
    }

}

同樣,您不需要設置項目符號的名稱,因為您的預制項目符號應該已經被命名為“ bullet”。

我希望這可以幫助您朝正確的方向開始。 但是根據您的代碼,我強烈建議您在繼續任何項目之前通讀教程。 使他們變得團結一致的工作人員非常有幫助,教程開始時非常簡單,但很快就會變得非常復雜,因此您實際上可以學到很多東西!

也許問題出在玩家的父轉換上。 您可以嘗試執行以下操作,以確保子彈具有正確的父項:

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

如果這不起作用,則值得檢查玩家的Rect變換以查看錨點和樞軸的位置。 也許玩家的實際“位置”坐標不在您認為的位置。

您完成了Space Shooter教程嗎? 它有一段關於發射子彈的內容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM