Jump to content
Unity Insider Forum

Collider buggt sich durch Terrain


Timbo3

Recommended Posts

Hallo Forum, wie der Titel schon sagt habe ich ein Problem mit meinem Terrain.

Wenn der Spieler mit normaler Geschwindigkeit läuft(Translate) kollidiert er mit den Hügeln wenn er aber rennt, buggt sich der Spieler einfach durch

hier das Player Script:

using UnityEngine;
using System;

public class Player : MonoBehaviour
{
    public int yRotate;
    public int xRotate;
    public Transform cam;
    public float minRotation = -45;
    public float maxRotation = 45;
    float mouseRot = 0;
    public float walkingSpeed = 15;
    private float walkSpeed = 15;
    public float runningSpeed = 30;
    public float sneakSpeed = 5;
    public float sneakHigh = 0.8f;
    public float PlayerHeigh = 1;
    private bool onGround = true;
    public float jumpForce = 10000;
    public Rigidbody rb;

    void Start()
    {
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
        transform.localScale += new Vector3(0, PlayerHeigh - transform.localScale.y, 0);
    }

    void Update()
    {
        mouseRot += Input.GetAxis("Mouse Y") * yRotate;
        mouseRot = Mathf.Clamp(mouseRot, minRotation, maxRotation);
        Vector3 rot = new Vector3(mouseRot, 0, 0);
        cam.localRotation = Quaternion.Euler(-rot);
        transform.Rotate(0, Input.GetAxis("Mouse X") * xRotate, 0);


    }

    void FixedUpdate()
    {
        if (Input.GetKey("w"))
        {
            transform.Translate(0, 0, 1 * walkSpeed * Time.deltaTime);
        }
        if (Input.GetKey("s"))
        {
            transform.Translate(0, 0, -1 * walkSpeed * Time.deltaTime);
        }
        if (Input.GetKey("a"))
        {
            transform.Translate(-1 * walkSpeed * Time.deltaTime, 0, 0);
        }
        if (Input.GetKey("d"))
        {
            transform.Translate(1 * walkSpeed * Time.deltaTime, 0, 0);
        }
        if (Input.GetKey("space") && onGround == true)
        {
            onGround = false;
            rb.AddForce(transform.up * jumpForce);
        }
        if (Input.GetKeyDown(KeyCode.LeftControl))
        {
            walkSpeed = runningSpeed;
        }
        if (Input.GetKeyUp(KeyCode.LeftControl))
        {
            walkSpeed = walkingSpeed;
        }
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            walkSpeed = sneakSpeed;
            transform.localScale += new Vector3(0, sneakHigh - transform.localScale.y, 0);
        }
        if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            walkSpeed = walkingSpeed;
            transform.localScale += new Vector3(0, PlayerHeigh - transform.localScale.y, 0);
        }
    }
    private void OnCollisionEnter(Collision col)
    {
        if (col.gameObject.tag == "Terrain")
        {
            onGround = true;
        }
    }

}


Und die Einstellungen von Spieler und Terrain:

http://prntscr.com/nrwlz7

http://prntscr.com/nrwnx2

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Transform.Translate ignoriert sämtliche Physik und bewegt das Objekt stumpf so, wie du es ihm sagst. Wenn dein Objekt in bestimmten Situationen nicht durch die Collider bugt, dann liegt das einzig daran, dass Rigidbodys in jedem Physik-Update einmal schauen, ob sie irgendwo drinstecken. Wenn ja, dann bewegen sie sich aus dem anderen Collider heraus. Dabei wird natürlich nicht mehr berücksichtigt, aus welcher Richtung das Objekt ursprünglich gekommen ist, um in dem anderen Collider zu landen. Wenn du also nur weit genug in irgendetwas reingehst, geht der Rigidbody einfach auf der anderen Seite wieder heraus, weil's der kürzere Weg ist.

Lange Rede, kurzer Sinn: Niemals Transform.Translate benutzen, wenn du Kollisionsabfrage haben willst. Es gibt eine Reihe von Möglichkeiten, die tatsächlich direkt Kollisionsabfragen integriert haben:

  1. CharacterController benutzen. Der ist genau für humanoide Charaktere da und sehr einfach zu kontrollieren. Statt Transform.Translate benutzt du CharacterController.Move.
  2. Einen Rigidbody bewegen lassen. Anstatt deines Scripts kontrolliert der Rigidbody deine Position. Die Geschwindigkeit des Rigidbodys kontrollierst du dann mit AddForce oder über velocity.
  3. NavMeshAgent benutzen. Wenn der Spieler nur auf einer vorgegebenen Fläche laufen können muss (und nicht z.B. von Plattform zu Plattform springen kann), dann kannst du ein NavMesh bauen und da einen NavMeshAgent drüberschicken. Geht auch recht einfach.
  4. Eigene Kollisionsabfragen. Ist eher was für Fortgeschrittene, aber wenn keine der anderen drei Varianten dir das gewünschte Ergebnis geben kann (heißt nicht, dass du beim ersten Problem sofort aufgeben solltest :)), dann kann man auch sein ganz eigenes System bauen.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Nein. Zum einen ist das wie gesagt nur die letzte Variante, wenn alle anderen wirklich nicht in deiner spezifischen Situation funktionieren, weil alle drei ganz hervorragend sind. Zum anderen ist der Kern von Variante 4, dass es da eben nicht "den Weg" gibt, wie man das macht, sondern man eben eine ganz eigene Lösung baut. Die Basis ist, sofern man bei der Standard-Physik-Engine bleibt, die Physics- (bzw. die Physics2D-)Klasse. Aber ab da wird jede Anleitung sinnlos, weil es hier im Kern um eine maßgeschneiderte Lösung geht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Btw kannst du statt immer Input.GetKey(w),  Input.GetKey(s) etc. zu benutzen einfach mit Input.GetAxis(""Vertical") und das selbe für Horizontal. Finde so wird der Code viel übersichtlicher und es geht beim zweiten mal schneller. Kannst es ja mal nachlesen wen du willst :)

https://docs.unity3d.com/ScriptReference/Input.GetAxis.html

Gibt auch genug Youtube Tutorials dafür.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...