How to move an object in local to it's parent while keeping with the parent rotation

I’m trying to move my waypoints if they get inside a wall when the player moves too close for my simple followers. I tried positioning these anchors based off the player’s position only to realize they dont rotate to stay behind them anymore. I tried transform.localPosition, as you can see in the last if statement that resets them if nothing is blocking the way, but it just ends up putting sticking them here, and my code is below:
EDIT: couldnt get image to work, here it is

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnchorManipulator : MonoBehaviour
{
    public WallDetector[] wallDetectors;
    public GameObject[] followAnchors;

    // Start is called before the first frame update
    void Awake()
    {

    }

    // Update is called once per frame
    void Update()
    {
        //change follow anchor position based on what detectors are colliding with something
        //left side obstacle
        if (wallDetectors[0].obstacleHere == true && wallDetectors[1].obstacleHere == false && wallDetectors[2].obstacleHere == false)
        {
            followAnchors[0].transform.position = gameObject.transform.position + new Vector3(2.5f, 1, -2);
            followAnchors[1].transform.position = gameObject.transform.position + new Vector3(0, 1, -2);
        }
        //left and directly behind obstacle
        if (wallDetectors[0].obstacleHere == true && wallDetectors[1].obstacleHere == true && wallDetectors[2].obstacleHere == false)
        {
            followAnchors[0].transform.position = gameObject.transform.position + new Vector3(2, 1, -2);
            followAnchors[1].transform.position = gameObject.transform.position + new Vector3(2, 1, 2);
        }
        //directly behind obstacle only MAY NOT BE NECCESARY I ONLY PUT THIS IN FOR FEELS IF ITS BAD REMOVE IT
        if (wallDetectors[0].obstacleHere == false && wallDetectors[1].obstacleHere == true && wallDetectors[2].obstacleHere == false)
        {
            followAnchors[0].transform.position = gameObject.transform.position + new Vector3(2, 1, -1);
            followAnchors[1].transform.position = gameObject.transform.position + new Vector3(2, 1, -1);
        }
        //Right side obstacle
        if (wallDetectors[0].obstacleHere == false && wallDetectors[1].obstacleHere == false && wallDetectors[2].obstacleHere == true)
        {
            followAnchors[0].transform.position = gameObject.transform.position + new Vector3(0, 1, -2);
            followAnchors[1].transform.position = gameObject.transform.position + new Vector3(-2.5f, 1, -2);
        }
        //Right and Behind obstacle
        if (wallDetectors[0].obstacleHere == true && wallDetectors[1].obstacleHere == true && wallDetectors[2].obstacleHere == false)
        {
            followAnchors[0].transform.position = gameObject.transform.position + new Vector3(2, 1, -2);
            followAnchors[1].transform.position = gameObject.transform.position + new Vector3(-2, 1, 2); followAnchors[1].transform.position = gameObject.transform.position + new Vector3(5, 0, -4);
        }
        //All Blocked
        if (wallDetectors[0].obstacleHere == true && wallDetectors[1].obstacleHere == true && wallDetectors[2].obstacleHere == true)
        {
            followAnchors[0].transform.position = gameObject.transform.position + new Vector3(2, 1, 2);
            followAnchors[1].transform.position = gameObject.transform.position + new Vector3(-2, 1, 2);
        }
        //right and left blocked
        if (wallDetectors[0].obstacleHere == true && wallDetectors[1].obstacleHere == false && wallDetectors[2].obstacleHere == true)
        {
            followAnchors[0].transform.position = gameObject.transform.position + new Vector3(0, 1, -2);
            followAnchors[1].transform.position = gameObject.transform.position + new Vector3(0, 1, -4);
        }
        //all clear
        if (wallDetectors[0].obstacleHere == false && wallDetectors[1].obstacleHere == false && wallDetectors[2].obstacleHere == false)
        {
            followAnchors[0].transform.position = gameObject.transform.localPosition + new Vector3(2, 1, -2);
            followAnchors[1].transform.position = gameObject.transform.localPosition + new Vector3(-2, 1, -2);
        }

    }
}

Also if I’m a dumbass for doing my pathfinding this way please call me out on it, this is a good learning experience for me.

You’re setting the world position of your followAnchors based on the local position of your gameObject, which is just a mess of different spaces. If you explicitly set the localPosition of the followAnchors instead, they’ll always be positioned in respect to the rotation of the parent.

parentTransform.rotation = Random.Rotation;
childTransform.localPosition = new Vector3(2.0f, 0f, 0f); // this will always be 2 units to the right of the parent's position regardless of its rotation

You’re also using a bunch of if statements, not if-else, so the follower logic will actually be bottom-up where whichever if statement fires last determines your order.

I already fixed it this morning by changing both sides of the operator to be localPosition. Even without the if-else statements it seems to be working as intended. Order doesn’t seem to matter here since only one can be true at once unless there’s some way to make performance better. I’ve also made it to where the game will only try this every 10 frames instead of raw update if it even needs to do this at all, based on if one or more of the colliders is contacting an obstacle.

1 Like