簡體   English   中英

2D對象Collison Unity

[英]2D Object Collison Unity

我正在Unity中開發一個簡單的2D游戲,在處理碰撞時遇到了問題。 我有兩個對象,一棵樹和一個播放器。 這棵樹不動,由一些精靈和一個多邊形對撞機表示。 玩家使用自定義腳本(不是角色控制器)移動,並具有運動 Ridgidbody和多邊形對撞機。

我的預期行為是讓玩家與樹“碰撞”並被樹阻擋,因此所有對象都無法移動。 但是,這似乎不是執行此操作的簡單方法。

將樹的RidgidBody組件設置為“靜態”或“動態”不會導致檢測到碰撞。 我考慮過將播放器變成“動態”剛體,但是統一文檔建議動態剛體不應該通過其變換組件移動,這就是我當前系統的工作方式。 此外,將其設置為動態會導致意外行為,導致播放器無緣無故死機,並且由於不會在播放器對象上應用任何物理方法,因此對於動態而言,這似乎是一個糟糕的用例。 我對此可能是錯的。

當碰撞事件觸發時,我可以使用腳本以某種方式鎖定玩家的位置,但這似乎很棘手。 誰能提供一些有關如何處理此問題的見解?

顯然2D粘菌很臭。 這是避免此問題的一些方法。 基本上不依賴於對撞機,它使用光線投射來檢查玩家試圖移動的障礙物是否存在

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Player : MovingObjects {

    protected override void AttemptMove<T> (int xDir, int yDir)
    {
        base.AttemptMove<T> (xDir, yDir);
        RaycastHit2D hit;       
    }
    protected override void onCantMove<T>(T component)
    {
        Wall hitwall = component as Wall;
        hitwall.DamageWall (wallDamage);        
    }

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

        int horizontal = 0;
        int vertical = 0;

        horizontal = (int)Input.GetAxisRaw ("Horizontal");
        vertical = (int)Input.GetAxisRaw ("Vertical");

        if (horizontal != 0)
            vertical = 0;

        if (horizontal != 0 || vertical != 0)
            AttemptMove<Wall> (horizontal, vertical);
    }
}

繼承自:

using UnityEngine;
using System.Collections;

public abstract class MovingObjects : MonoBehaviour {

    public float moveTime = 0.1f;
    public LayerMask blockingLayer;

    private BoxCollider2D boxCollider;
    private Rigidbody2D rb2D;
    private float inverseMoveTime;

    protected virtual void Start()
    {
        boxCollider = GetComponent<BoxCollider2D> ();
        rb2D = GetComponent <Rigidbody2D>();
        inverseMoveTime = 1f / moveTime;

    }


    protected IEnumerator SmoothMovement(Vector3 end)
    {
        float sqrRemaininDistance = (transform.position - end).sqrMagnitude;

        while (sqrRemaininDistance > float.Epsilon) {

            Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime*Time.deltaTime);

            rb2D.MovePosition(newPosition);
            sqrRemaininDistance = (transform.position - end).sqrMagnitude;

            yield return null;
        }
    }

    protected bool Move(int xDir, int yDir, out RaycastHit2D hit)
    {
        Vector2 start = transform.position;
        Vector2 end = start + new Vector2 (xDir, yDir);

        boxCollider.enabled = false;

        hit = Physics2D.Linecast (start, end, blockingLayer);

        boxCollider.enabled = true;

        if (hit.transform == null) {

            StartCoroutine(SmoothMovement(end));
            return true;
        }

        return false;
    }

    protected virtual void AttemptMove<T>(int xDir, int yDir)
                            where T : Component
    {

        RaycastHit2D hit;
        bool canMove = Move (xDir, yDir, out hit);

        if (hit.transform == null)
            return;


        Debug.Log ("Something hit", gameObject);

        T hitComponent = hit.transform.GetComponent<T> ();

        if (!canMove && hitComponent != null)
            onCantMove (hitComponent);


    }

    protected abstract void onCantMove<T>(T component)
                       where T: Component;

}

該腳本屬於官方Unity網站的教程。 一個名為Rogue的2D游戲。 如果您打算做類似的事情,這里是鏈接:

https://unity3d.com/es/learn/tutorials/projects/2d-roguelike-tutorial

暫無
暫無

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

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