this is where I meant to post the code I’m using for this question. Here it is. Still doesn’t seem to be working
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeBall_02 : MonoBehaviour
{
public GameObject child;
public Transform Player_02;
private void OnCollisionEnter(UnityEngine.Collision collision)
{
if (collision.gameObject.name == "Player_01")
{
child.transform.SetParent(Player_02, true);
}
}
}
Well, get to debugging, same as Kurt posted in your other thread. “It doesn’t seem to be working” isn’t the point at which you start posting on the forums - it’s the point at which you start debugging.
Got something working here … not behaving as smoothly as I would like. The transfer of the child object is kind of rocky.
Must be because I’m updating the parent to be true every frame. Hmm …
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class BallCarrier : MonoBehaviour
{
public GameObject child;
public Transform parent;
public Transform newParent;
// Update is called once per frame
void Update()
{
child.transform.SetParent(parent, true);
}
private void OnCollisionEnter(UnityEngine.Collision collision)
{
if (collision.gameObject.name == "Player_02")
child.transform.SetParent(newParent, true);
child.transform.SetParent(parent, false);
}
}
You will need to be a lot more specific. Are you trying to make it so that, when two players touch, the ball moves from a specific spot on one player to a specific spot on another player?
As-is, the ball will just get attached to the other player at whatever position it happened to be in when they touched.
If that’s what you want, I’d suggest adding empty gameobjects representing where the player’s hands are and parenting the ball to that. Then, you can lerp the ball’s local position towards Vector3.zero to make it snap to the second player’s hand.
Whilst re-applying WorldPosition to the child every frame.
There are many instances in which it’s easy to create some fun ‘race-conditions’ there.
You’re not ‘updating the parent to be true’.
You’re re-parenting it to that parent, and doing this whilst keeping the current worldspace-position (that’s what the ‘true’ (bool worldPositionStays) does). https://docs.unity3d.com/ScriptReference/Transform.SetParent.html
Thus, every frame you’re:
Setting the Current Parent in child to NULL
Applying the parent’s WorldSpace-Position, -Rotation & -Scale to your LocalToParent-Transform to calculate the new Transformation-Matrix for the child (since it no longer has a parent).
Re-setting the Parent to what it actually was before
Creating a new LocalToParent-Matrix to fit to the current LocalToWorld-Matrix.
tl;dr don’t reparent (with worldPositionStays) every frame.
Well. The “ball” just designates “possession”. So, I switched over to an empty game object and it’s working as I want it to.
Have a new problem, however. I want to set it up so that if player_01 collides with player_02 ON target_01, we get a result. Specifically the parent of the child object changes. And that’s fine. They each work independently, just not together.
Here’s what I’ve been working with. I don’t quite know if this is even possible within the limits of unity. The script is written for player 01, the place is the target, and player 2 is the second condition
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class BallCarrier : MonoBehaviour
{
public GameObject child;
public Transform parent;
public Transform newParent;
void Start()
{
child.transform.SetParent(parent, true);
}
private void OnCollisionStay(UnityEngine.Collision collision)
{
if ((collision.gameObject.name == "Plane") && (collision.gameObject.name == "Player_02"))
{
child.transform.SetParent(newParent, true);
}
}
}
Maybe this is what you’re looking for. It requires a collider, a rigidbody, and this script on each player. I added a one second wait coroutine to keep the ball from instantly passing back and forth if they continue to collide in quick succession.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallCarrier : MonoBehaviour {
public Transform ball;
public Transform myTransform;
public Transform otherPlayer;
[HideInInspector] public bool hasBall = false;
bool waiting = false;
void Start () {
if (myTransform.gameObject.name == "Player 1") {
ball.transform.SetParent (myTransform);
hasBall = true;
}
if (myTransform.gameObject.name == "Player 2") {
hasBall = false;
}
}
void OnCollisionEnter (Collision collider) {
if (collider.transform == otherPlayer && hasBall && !waiting) {
ball.SetParent (otherPlayer);
hasBall = false;
BallCarrier ballCarrier = otherPlayer.GetComponent <BallCarrier> ();
ballCarrier.hasBall = true;
StartCoroutine (ballCarrier.Wait ());
StartCoroutine (Wait ());
}
}
IEnumerator Wait () {
waiting = true;
yield return new WaitForSeconds (1f);
waiting = false;
}
}
Damn. Thanks for all the effort. That’s some beautiful script. Can’t image building something like that in a million years.
Got another problem, if you’re interested. I’m full of problems. Lol.
I’ve got to get the collision between player 01 and player 02 to happen (or “register”) on a certain “place” (for example). Just a target region. Player 01 can only steal possession of the ball from player 02 on designated targets (and vice versa)
I’ve messed with adding two conditions to an OnCollisionStay command. (so that player 01 collides with the target at the same time that player 2 collides with the target, and then the exchange of the ball occurs). But that seems to have some problems …?
That was the last component of my game. Can’t say I didn’t bust my rump the last couple of weeks learning how to code. But this is one hurdle where I’ll be VERY happy to accept some helping hands.