Jump to content
Unity Insider Forum
Timbo3

Collider buggt sich durch Terrain

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

 

Share this post


Link to post
Share on other sites

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.
  • Like 1

Share this post


Link to post
Share on other sites

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.

  • Like 1

Share this post


Link to post
Share on other sites

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.

  • Like 1

Share this post


Link to post
Share on other sites

Zum Thema der verschiedenen Bewegungsmöglichkeiten hat @malzbie ein tolles Video erstellt:

 

Ist zwar schon etwas älter, aber im Grunde noch immer aktuell. Hier wird auch auf das eingegangen, was @Sascha oben zu den RB geschrieben hat.

Share this post


Link to post
Share on other sites
vor 3 Stunden schrieb Timbo3:

Kann man Themen auch irgendwie als gelöst markieren?

Nö, machen wir bei uns nicht.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...