简体   繁体   English

unity C# 脚本旋转偏移

[英]Unity C# script rotation offset

I've been tinkering with this for a while and can't seem to get it to work properly, it sometimes works but other times does not.我已经对此进行了一段时间的修补,但似乎无法使其正常工作,它有时可以工作,但有时却不能。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class gun: MonoBehaviour
{
    public Transform firePoint;
    public GameObject BulletPrefab;
    
    float Speed = 20f;
    
    void Update()
    {
        if(Input.GetButtonDown("Fire1"))
        {
            Shoot();
        }
    }
    
    void Shoot()
    {
        int a = 0;
        float[] b1 = {-15f,0f,15f};
    
        while (a != 3)
        {
            GameObject bullet = Instantiate(BulletPrefab, firePoint.position, firePoint.rotation);
    
            Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
            Transform tr = bullet.GetComponent<Transform>();
            tr.rotation = firePoint.rotation;
            tr.Rotate(new Vector3(0f,0f,b1[a]),Space.Self);
            rb.AddForce(tr.up * Speed, ForceMode2D.Impulse);
  
            a++;
        }   
    }
}

It's supposed to offset the projectiles at 15 degrees angles and shoot them, but sometimes it just rotates inwards and shoots straight forward.它应该以 15 度角偏移弹丸并射击它们,但有时它只是向内旋转并直接向前射击。

Tried to convert it to vectors and back but have no clue how to do that and can't seem to find help on this even on page 2 of Google.试图将它转换为矢量并返回,但不知道如何做到这一点,甚至在谷歌的第 2 页上似乎也找不到这方面的帮助。

I believe that, from the few information that are present, you want to "triple shoot" your bullets from your gun position and make it go forward depending on your gun rotation and rotation offset?我相信,根据现有的少量信息,您想从枪 position 中“三次发射”子弹,并根据枪的旋转和旋转偏移使其向前移动 go? If so then here are the problems and solutions to your code:如果是这样,那么这里是您的代码的问题和解决方案:

The problem问题

I recommend using tr.eulerAngles which uses Vector3 and it's easier to understand and manipulate.我推荐使用tr.eulerAngles ,它使用 Vector3,它更容易理解和操作。 With that, you can simply do:有了它,您可以简单地执行以下操作:

tr.eulerAngles = firePoint.transform.eulerAngles

This will make your bullet copy the gun rotation.这将使你的子弹复制枪的旋转。 Now, if you want to add some rotation to your bullet to make a "triple shot" effect, you would only need to add a Vector3 to modify the y value of your angle.现在,如果您想为子弹添加一些旋转以产生“三次射击”效果,您只需要添加一个 Vector3 来修改角度的y值。 Example:例子:

tr.eulerAngles = firePoint.transform.eulerAngles + new Vector3(0, -15, 0);

This will fix your problem with rotation.这将解决您的旋转问题。

Tips to upgrade your code升级代码的提示

Even though this simply line of code will fix your problem, your script has a lot of issues with proper coding and video games basic rules.尽管这行简单的代码可以解决您的问题,但您的脚本在正确编码和视频游戏基本规则方面存在很多问题。

First rule of video games, is to never instantiate object during Runtime.视频游戏的第一条规则是永远不要在运行时实例化 object。
Why?为什么? Let's say you shoot 10 bullets at once with a fast firerate, then your game will be very laggy because you are instantiating new objects in your memory (and erasing afterwards).假设您以快速射速一次发射 10 发子弹,那么您的游戏将非常滞后,因为您正在实例化 memory 中的新对象(并随后擦除)。 It's a very beginner issue that simply requires the use of Object Pooling .这是一个非常初学者的问题,只需要使用Object 池

Another tip is to better name your variables and respect naming conventions.另一个技巧是更好地命名变量并遵守命名约定。 Instead of using 1-2 letter(s) variables use understandable key-words:不要使用 1-2 个字母变量,而是使用可理解的关键字:

tr -> transform tr -> 变换
a -> rotationOffset a -> 旋转偏移量
BulletPrefab -> bulletPrefab BulletPrefab -> bulletPrefab
Speed -> speed速度 -> 速度

You should learn the conventions so your code is more clear for others but also for yourself.您应该学习约定,这样您的代码对其他人和您自己来说都更加清晰。

Last tip, if your loop can predict it's end (in this case it's a triple shot so it's from 0 to 3 exclusive) then you should use a for() instead of while() loop.最后一个提示,如果你的循环可以预测它的结束(在这种情况下它是一个三重镜头所以它是从 0 到 3 独占)那么你应该使用 for() 而不是 while() 循环。

I highly recommend you to check out some basic coding lessons/tutorials, it will save you from lot of issues in the future.我强烈建议您查看一些基本的编码课程/教程,它将避免您将来遇到很多问题。

Some general suggestions here这里有一些一般性建议

First make your Inspector exposed field of the correct type right away首先让您的 Inspector 立即暴露正确类型的字段

public Rigidbody2D bulletPrefab;

this way you ensure the referenced object actually has such a component and don't need GetComponent later.这样你就可以确保引用的 object 实际上有这样一个组件,以后不需要GetComponent

Then you create an array everytime you shoot.. rather have it persistent然后你每次拍摄时都创建一个数组..而不是让它持久

 private static readonly float[] offsets = {-15f,0f,15f};

then usually you would use a proper for loop and iterate over the actual size of the array instead of using a while那么通常您会使用适当for循环并迭代数组的实际大小,而不是使用while

for(var i = 0; i < offsets.Length; i++)
{
    ...
}

and finally you shouldn't go through transform at all when using physics but only the Rigidbody2D and do eg最后你不应该 go through transform when using physics 但只有Rigidbody2D并且做例如

void Shoot()
{

    for(var i = 0; i < offsets.Length; i++)
    {
        var bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation * Quaternion.Euler(0, 0, offsets[i]));
        rb.AddForce(Quaternion.Euler(0, 0, rb.rotation * Vector3.up * Speed, ForceMode2D.Impulse);
    }   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM