Sixnine Geschrieben 8. Mai 2021 Melden Share Geschrieben 8. Mai 2021 Hey Leute, ich hab mich hier mal neu ins Forum gewimmelt, weil ich mit einem Problem nicht zurecht komme. Ich auf nem simplen Rigidbody First Person Controller meinen Aufheben-Script attached. Er bewirkt, dass man, sobald man ein Objekt aufhebt, es an den Spieler geparented wird und keine Gravitation hat. Nun, wenn das aufgehobene Objekt kollidiert, will ich diese komischen Rotationen und Repositionings beseitigen.Bitte das Video dazu gucken: https://drive.google.com/file/d/10Iu1vvYafrub2zajdAjT2-RE88Jre_Nu/view?usp=sharing Ich hab schon ma probiert, die Position und Rotation zu speichern, bevor das Objekt kollidiert, und dann in einem FixedUpdate() die Position dauernd zurückzusetzen. Allerdings muss mein Script wieder erkennen, wenn "der Spieler wieder nach oben guckt", wenn ihr versteht was ich meine. Danke für Eure wertvolle Zeit! LG Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 8. Mai 2021 Autor Melden Share Geschrieben 8. Mai 2021 [[Nicht wundern Video wurde grad geuploaded bei Google Drive, heißt dass es noch 14 min dauert o. so bis FullHD verfügbar ist]] Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 8. Mai 2021 Melden Share Geschrieben 8. Mai 2021 Moin! Du schaltest von dem Item also nur die Gavitiation aus? Warum nicht den ganzen Rigidbody samt Collider? Einfach komplett aus der Gleichung rausnehmen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 10. Mai 2021 Autor Melden Share Geschrieben 10. Mai 2021 Hallo, erstmal vielen Dank für die Antwort. Und ja theoretisch könnte ich das machen, allerdings wollte ich, wie unnötig das auch klingen mag, etwas komplexeres ausprobieren. In meinem Fall wird das aufgehobene Item wieder losgelassen wenn der User die Maustaste loslässt oder das Crosshair nicht mehr auf dem Objekt ist. [Das passiert bei Objektkollisionen] Ich hab mir in der Zwischenzeit aber noch Gedanken dazu gemacht.. Bei einer Kollision muss ich wissen, welche "Kante" kollidiert ist, um die entsprechende Positionierung und Rotation auf den entsprechenden Axen zu freezen. Wichtig bei mir ist auch, dass das bei nem Mesh Collider funktioniert, denn bei meinem Projekt habe ich auch sämtliche Props, die komplexere Meshes zur Collision Detection hervorziehen. LG Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 10. Mai 2021 Melden Share Geschrieben 10. Mai 2021 Wenn das Objekt den Collider behalten soll, kannst du mit Physics.IgnoreCollision die Kollision mit dem Spieler ausschalten. Layer-basiertes Ignorieren ginge auch, ist aber so eine Sache, den Player und das Objekt deswegen extra auf dafür vorgesehene Layer zu packen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 10. Mai 2021 Autor Melden Share Geschrieben 10. Mai 2021 Ok, aber das Problem was ich grade lösen wollte ist, dass das Objekt, wenn es z. B. auf den Boden kollidiert, und der Spieler weiter nach unten guckt, nicht die "komischen" Rotationen entstehen. [das Video veranschaulicht das etwas besser]. Die Rotationen entstehen ja, weil das aufgehobene Item ein Child von der Camera ist und die Rotation dann entsprechend angepasst wird, auch wenn das Objekt kollidiert. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 10. Mai 2021 Autor Melden Share Geschrieben 10. Mai 2021 Vielleicht kurz nochmal zur Verdeutlichung was ich meine:https://photos.app.goo.gl/hnWREcaeRVhgxYiN6 Dieses "Hochbuggen" wenn man das Objekt an den Boden presst. ... oder auch an eine andere Wand, dann ist das "Buggen" auf einer anderen Achse Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 10. Mai 2021 Melden Share Geschrieben 10. Mai 2021 Achso, sorry, falsch verstanden. Bei dem Problem kann man aber ohne dein Script nicht viel helfen Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 10. Mai 2021 Autor Melden Share Geschrieben 10. Mai 2021 Okay, ich such den kurz raus Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 10. Mai 2021 Autor Melden Share Geschrieben 10. Mai 2021 Okay hier mein Script zum Aufheben (bisschen lang, denn da ist noch so was wie Werfmechanik und weiteres drinne): using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerPickUp : MonoBehaviour { [Header("Script functionalities")] [SerializeField] Transform cam; [SerializeField] float playerWidth = 1f; [Header("Pick up system")] [SerializeField] float range = 5f; [SerializeField] bool enableThrowing = true; [SerializeField] float throwForce = 5f; [SerializeField] float throwCompression = 2f; [Header("Advanced holding options")] [SerializeField] bool enableLeaveCrosshairDrop = true; [SerializeField] bool enableOutOfRangeDrop = true; float fire1; float fire2; float fire1_before; float fire2_before; Transform virtualObj; // Start is called before the first frame update void Start() { } // Update is called once per frame private void Update() { InitializeInput(); } void InitializeInput() { fire1 = Input.GetAxisRaw("Fire1"); fire2 = Input.GetAxisRaw("Fire2"); } void FixedUpdate() { PickupAndDrop(); InCaseDrop(); CustomObjCorrection(); Throwing(); fire1_before = fire1; fire2_before = fire2; } void PickupAndDrop() { if (fire1 != fire1_before && fire2 <= 0) { if (fire1 >= 1) { ItemIdentifier ident = (ItemIdentifier)StaticFunctions.forwardRay(typeof(ItemIdentifier), cam, playerWidth, range); if (ident != null) { if (ident.isProp) { holdingObj = ident.transform; } } } else { holdingObj = null; } } } void InCaseDrop() { if (holdingObj != null) { if (enableLeaveCrosshairDrop) { float usedRange = enableOutOfRangeDrop ? range : Mathf.Infinity; if ((Transform)StaticFunctions.forwardRay(typeof(Transform), cam, playerWidth, usedRange) != holdingObj) { holdingObj = null; } } if (enableOutOfRangeDrop && holdingObj != null) { float distance = Vector3.Distance(cam.position + cam.forward * playerWidth / 2, holdingObj.position); if (distance > range) { holdingObj = null; } } } } void CustomObjCorrection() { if (holdingObj != null) { holdingObj.GetComponent<Rigidbody>().velocity = Vector3.zero; holdingObj.GetComponent<Rigidbody>().angularVelocity = Vector3.zero; } } void Throwing() { if (fire2 != fire2_before && enableThrowing) { if (fire2 >= 1 && fire1 >= 1) { holdingObj.GetComponent<Rigidbody>().AddForce(cam.forward * throwForce + Vector3.up * throwCompression, ForceMode.Impulse); holdingObj = null; } } } Transform _holdingObj = null; Transform holdingObj { get { return _holdingObj; } set { if (_holdingObj != null) { _holdingObj.GetComponent<Rigidbody>().useGravity = true; _holdingObj.GetComponent<Rigidbody>().freezeRotation = false; _holdingObj.parent = null; } _holdingObj = value; if (_holdingObj != null) { _holdingObj.GetComponent<Rigidbody>().useGravity = false; _holdingObj.GetComponent<Rigidbody>().freezeRotation = true; _holdingObj.parent = cam; } } } } Bei diesen StaticFunctions Dingern handelt es sich noch um eine statische Klasse, mit der ich von mir vordefinierte "Raycast-Presets" benutzen kann. using System.Collections; using System.Collections.Generic; using UnityEngine; public static class StaticFunctions { public static object forwardRay(System.Type t, Transform origin, float originWidth, float range = Mathf.Infinity) { RaycastHit hit; bool hasHit; if (range != Mathf.Infinity) { hasHit = Physics.Raycast(origin.position + origin.forward * originWidth / 2, origin.forward, out hit, range); } else { hasHit = Physics.Raycast(origin.position + origin.forward * originWidth / 2, origin.forward, out hit); } if (t == typeof(bool)) { return hasHit; } else if (hasHit) { if (t == typeof(RaycastHit)) { return hit; } if (t == typeof(Transform)) { return hit.collider.transform; } else if (t == typeof(ItemIdentifier)) { return hit.collider.GetComponentInParent<ItemIdentifier>(); } } return null; } public static RaycastHit[] forwardRayAll(Transform origin, float originWidth, float range = Mathf.Infinity) { Vector3 rayStart = origin.position + origin.forward * originWidth / 2; if (range != Mathf.Infinity) { return Physics.RaycastAll(rayStart, origin.forward, range); } else { return Physics.RaycastAll(rayStart, origin.forward); } } public static RaycastHit[] raysSortByDistance(RaycastHit[] src) { List<RaycastHit> srcList = new List<RaycastHit>(src); float[] distances = new float[srcList.Count]; for (int i = 0; i < srcList.Count; i++) { distances[i] = srcList[i].distance; } System.Array.Sort(distances); List<RaycastHit> sortedList = new List<RaycastHit>(); List<int> usedHitsIndices = new List<int>(); for (int i = 0; i < distances.Length; i++) { for (int ii = 0; ii < srcList.Count; ii++) { if (distances[i] == srcList[ii].distance && !usedHitsIndices.Contains(ii)) { sortedList.Add(srcList[ii]); usedHitsIndices.Add(ii); continue; } } } return sortedList.ToArray(); } } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 11. Mai 2021 Autor Melden Share Geschrieben 11. Mai 2021 Um den ganzen Kram einfach kurz zu fassen: Wenn ich ein Objekt aufhebe dann mache ich drei Sachen: Ich schalte die Rigidbody Gravitation des Objekts aus Ich schalte die Rigidbody Freeze Rotation des Objekts auf an Ich setze den Parent des Objekts auf meine Spielerkamera. Wenn ich es fallen lasse, mache ich genau diese Schritte wieder rückgängig. Ich hab da auch schon einen Ansatz wie ich das fixxen könnte. Dazu müsste ich bei einer Kollision erfahren, welche "Kante" des Objekts kollidiert ist, und dessen Position auslesen können. Ich schau nochmal im Web nach, ob ich dazu was finde- Nicht wundern, programmieren tu ich schon bisschen länger, in Unity noch nicht so lang, deshalb diese Fragen. LG Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sixnine Geschrieben 11. Mai 2021 Autor Melden Share Geschrieben 11. Mai 2021 Kurzes Update, ich bin jetzt auf collision.contacts gestoßen, damit kann ich feststellen, wo die Kollision stattgefunden hat. Dann kann ich herausfinden, welche Positions -und Rotationsachsen ich einfrieren muss. Ich gebe noch ein Update, sollte ich es hingekriegt haben oder warum nicht. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.