[英]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.