Unity,更改子对象的旋转。无法访问子对象

时间:2015-07-05 11:09:17

标签: unity3d rotation unityscript

我正在设计2D游戏中玩家瞄准和射击的逻辑。当用户点击并拖动屏幕时,应该围绕精灵旋转由3个点组成的线,其角度与玩家拖动的角度相同,这样他就可以瞄准。就像泡泡射手一样。

"播放器" prefab有一个名为" Sight"这是一个具有4个点精灵的变换作为子对象及其相应的偏移,因此旋转"视线"将旋转整行。

enter image description here

在每个Update循环中,我看,根据鼠标位置旋转它,但似乎变量视觉为空。我试图通过标签获取对象,并有一个公共变量,以便我可以从检查器分配预制件。我还试图只抓取变换组件。我确定这是一个非常愚蠢的问题,但我无法看到它。我将不胜感激任何帮助。

瞄准逻辑:

public class PlayerShooting : MonoBehaviour {

    public GameObject BulletPrefab;
    public float coolDownTimer = 0.0f;
    public float aimDistance = 0.5f;

    private Vector2 originPoint = new Vector2 (0f,0f);
    private Vector2 endPoint = new Vector2(0f,0f);

    private bool dragging = false;
    public GameObject sight;

    // Update is called once per frame
    void Update () {

        // TOUCH DOWN
        if (Input.GetMouseButtonDown(0) == true) {
            originPoint = getPointInWorld(Input.mousePosition);
            endPoint = originPoint;
            dragging = true;
        }

        // TOUCH UP
        if (Input.GetMouseButtonUp(0) == true) {
            endPoint = getPointInWorld(Input.mousePosition);
            dragging = false;
            FireBullet();
        }

        // DRAGGING
        if (dragging) {


            endPoint = getPointInWorld(Input.mousePosition);
            // AIM
            // !!!: THIS IS THE ISSUE
            sight = GameObject.Find("Player/Sight");
            if (sight != null && endPoint != originPoint) {
                Vector2 dir = originPoint - endPoint;
                dir.Normalize();    
                float zAngle = Mathf.Atan2 (dir.y,dir.x) * Mathf.Rad2Deg - 90;
                Quaternion newRotation = Quaternion.Euler(0,0,zAngle);
                sight.transform.rotation = newRotation;
            }
            else
            {
                Debug.Log("Error: cannot aim because Sight was not instantiated");
            }
        }
    }

    void FireBullet (){

    }

    Vector2 getPointInWorld (Vector3 point){
        Vector2 pos = Camera.main.ScreenToWorldPoint(point);
        return pos;
    }
}

2 个答案:

答案 0 :(得分:1)

好的,您的脚本中有多个未经推荐的做法。如你所说,你应该更喜欢FindObjectWithTag,更好的是,通过检查器分配它。为此,请执行以下操作:创建名为sightReference的公共变量(或具有[Serializable]属性的私有)。然后保存您的脚本。将它附加到播放器后,拖动"视线" to sightReference,在检查器的脚本中(选择了播放器对象,如果扩展了脚本,则应该看到一个空字段);目前,它在您发布的图片中显示无(游戏对象),将视线拖到那里。

此外,为了检测拖动,您应该使用事件,而不是通过输入推断它。如果你想要一个关于事件的精彩教程,watch this one(你可以从头开始观看,但你需要的是在那个时间开始)。要么实现接口(我建议,即使一开始看起来很难,也很容易),或者统一使用事件触发器组件。

旧答案:

好吧,让我们说你希望这条线总是3点。我会做的是创建一个3点的精灵。这样,它只是一个对象(你可以用3个独立的精灵来做,但它可能会变得更复杂,所以为了简单起见,我会采用这个假设 - 你可以改变它更高版本)。

确保瞄准线精灵的枢轴点位于精灵的底部中间(您可以在线查找,将枢轴设置在精灵编辑器中)。您也可以将它保留在中间,并创建一个位于底部中间的父对象,并将其用作枢轴,但现在再次简单。

现在你有一个具有该精灵的物体,它围绕其枢轴点旋转,该枢轴点位于其底部中间,因此它就像钟针一样工作。尝试更改检查器中的旋转以验证。

现在,让这个瞄准线的父母成为玩家,以便它跟随玩家。调整其位置,使其与播放器不重叠。

现在,编写一个脚本并将其附加到瞄准线。在C#中:

void Update()
{
    Vector3 mouseWorldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Vector3 lineWorldPosition = this.transform.parent.position;
    Vector3 lookAtVector = mouseWorldPosition - lineWorldPosition;
    float angle = Mathf.Atan2(lookAtVector.x, lookAtVector.y) * Mathf.Rad2Deg;
    this.transform.localRotation = Quaternion.Euler(0, 0, -angle);
}

假设旋转0,0,0瞄准线与Y轴对齐(它指向上方)。

set it up like this

答案 1 :(得分:0)

退后一步,似乎没有对象可以分配给变量视线,因为场景文件已损坏。它是从Bitbucket存储库中克隆出来的。原始方法工作正常和指令

class UserContent(models.Model):
    """All user content must inherit this model"""

    date_created = models.DateTimeField(default=timezone.now)
    published = models.BooleanField(default=True)
    moderated = models.BooleanField(default=True)

    class Meta:
        abstract = True

能够找到对象。我决定从脚本而不是编辑器中分配它,这样如果玩家正在拍摄,我可以启用和禁用视线。