【问题标题】:Children not following parent孩子不跟随父母
【发布时间】:2014-04-29 15:22:14
【问题描述】:

我正在制作一个口袋妖怪克隆。 这是一个自上而下的基于瓷砖的 rpg。

所以我在玩家本身上添加了 4 个游戏对象。叫上、下、左、右。 我把它们放在播放器周围。我使用此设置来检查游戏对象是否已启动。正站在水面上。如果这是真的,那么玩家就不能上去。这是我解决碰撞的工作。但是我的孩子不想跟随我的父母。我所做的只是将 4 for gameobjects 拖到播放器上,并添加了这个 c# 脚本:

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{

    public LayerMask GroundLayer;
    Vector2 startPoint;
    Vector2 endPoint;
    private float increment;
    bool isMoving;
    public float speed;

    public tk2dTileMap tilemap;
    public GameObject up;
    public GameObject down;
    public GameObject left;
    public GameObject right;


    void Start()
    {
        startPoint = transform.position;
        endPoint = transform.position;


    }

    void Update()
    {


        if (increment <= 1 && isMoving == true)
        {
            increment += speed / 100;
        }
        else
        {
            isMoving = false;
        }

        if (isMoving)
        {
            transform.position = Vector2.Lerp(startPoint, endPoint, increment);
        }

        if (Input.GetKey(KeyCode.UpArrow) && isMoving == false)
        {
            if (MovementEvents(up) == 0)
            {
                move(up);
            }
        }
        else if (Input.GetKey(KeyCode.DownArrow) && isMoving == false)
        {
            if (MovementEvents(down) == 0)
            {
                move(down);
            }
        }
        else if (Input.GetKey(KeyCode.LeftArrow) && isMoving == false)
        {       
            if (MovementEvents(left) == 0)
            {
                move(left);
            }
        }
        else if (Input.GetKey(KeyCode.RightArrow) && isMoving == false)
        {
            if (MovementEvents(right) == 0)
            {
                move(right);
            }
        }
    }

    int MovementEvents(GameObject direction)
    {
        switch (tilemap.GetTileIdAtPosition(direction.transform.position, 0)) //gettileIdAtPosition returns the id of a tile in this case 0 is grass and 1 is water
        {
        case 0:
            return 0;
        default:
            return 1;   
        }
    }
    void move(GameObject direction)
    {
        increment = 0;
        isMoving = true;
        startPoint = transform.position;
        endPoint = direction.transform.position;
    }
}

我正在使用 2d 工具包。

我知道这可能是因为我以错误的方式设置它们,但我做错了什么?

【问题讨论】:

    标签: c# unity3d 2d


    【解决方案1】:

    您正在脚本(updown 等)中创建与您在编辑器中创建的对象无关的新 GameObjects。有两种解决方案:

    1) 您需要将updown 等分配给您在编辑器中创建的GameObjects。您可以通过编辑您的 Start 方法来包含:

    up = GameObject.Find( "up" );
    down = GameObject.Find( "down" );
    // etc.
    

    用您在编辑器中命名的up GameObject 替换"up"


    2) 使用

    updown 等作为子级分配给您的父级GameObject
    up.transform.parent   = parentGameObject.transform;
    down.transform.parent = parentGameObject.transform;
    // etc.
    

    注意,如果你走这条路线,那么你在编辑器中制作的updown等对象将不会被使用。您还需要翻译新对象(在设置其父对象之后),否则它们将仅位于相对于父对象的(0,0,0)

    编辑以响应 cmets

    如果我对问题的理解正确,那么您似乎只是在将updown 等对象添加为编辑器中的子对象时犯了一个错误。只需将它们全部拖到同一级别的父级上:

    然后每当TestParent 对象移动时,其他对象与父对象保持相同的相对位置,因此也会移动。然后,如果您将GameObjects 添加到这样的脚本中:

    您可以单独移动对象(同时仍然相对于父对象)。使用以下示例脚本,父对象以每秒一个单位向上移动 (Y+)。 Down 对象也以每秒额外一个单位的速度向上移动。这会导致ParentTestUpLeftRight 保持编队,每秒向上移动一个单位,而 Down 以每秒两个单位移动并缓慢移动。

    using UnityEngine;
    using System.Collections;
    
    public class DeleteMe : MonoBehaviour 
    {
        public GameObject Up;
        public GameObject Down;
        public GameObject Left;
        public GameObject Right;
    
        void Start( ) 
        {
    
        }
    
        // Update is called once per frame
        void Update( ) 
        {
            Move( gameObject );
            Move( Down );
        }
    
        private void Move( GameObject obj )
        {
            Vector3 position = obj.transform.position;
            position.y += UnityEngine.Time.deltaTime;
            obj.transform.position = position;
        }
    }
    

    一开始的截图:

    一段时间后又一个:

    最后请注意,您不需要在脚本中包含publicGameObjects,然后将它们拖放到脚本上即可访问子级。将脚本修改为:

        private GameObject Up;
        private GameObject Down;
        private GameObject Left;
        private GameObject Right;
    
        void Start( ) 
        {
            Up    = transform.Find( "Up" ).gameObject;
            Down  = transform.Find( "Down" ).gameObject;
            Left  = transform.Find( "Left" ).gameObject;
            Right = transform.Find( "Right" ).gameObject;
        }
    

    这避免了必须拖放到脚本本身的繁琐性质,还允许您访问可能动态添加到父级的子级,因此无法拖放。

    希望这有帮助!

    【讨论】:

    • 通过公开它们,我可以将编辑器中的游戏对象拖到脚本中。我还把游戏对象拖到玩家身上,所以他们应该是孩子?
    • 我没有机会准确地测试该方法,但我会在有机会时更新。
    • 感谢您的努力。赞赏。您所做的就是创建一个公共属性,您将看到一个添加脚本的新字段。只需将游戏对象从层次结构拖到空字段即可。关于育儿,只需将一个游戏对象拖到另一个上即可。
    • @NullReference 让我知道新信息是否有帮助
    猜你喜欢
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    相关资源
    最近更新 更多