0

enter image description hereI am able to set Y axis of my player with a simple transform.position call, in a single step, all within onTriggerEnter method, but the motion has a single step and is therefore jerky. Now I am trying to make the motion smooth by putting the transform.position function in an Update method within the same class. However, it seems that the position values determined/updated by onTriggerEnter method are not accessible in the Update function. If I print the x and z values to console, they contain expected values from onTriggerEnter function, but appear to be 0 when I print to console from the update function. Any ideas of what I am doing wrong? I would never call myself a programmer, so assume the worst :-) Thanks in advance for any help!

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


public class Step1SetElevation : MonoBehaviour
{
    private float moveSpeed = 3f;
    private float currX = 0.0f;
    private float currZ = 0.0f;
    private Vector3 currentPos;
    private GameObject player;
    private Collider other;

    void OnTriggerEnter(Collider other)
    {
    player = GameObject.FindWithTag("Player");
    currentPos = GameObject.Find("PlayerController").transform.position;
    currX = currentPos.x;
    currZ = currentPos.z;
    }

    void Update()
    {
    player = GameObject.FindWithTag("Player");
    player.transform.position = new Vector3(currX, 3.4f, currZ) * Time.deltaTime * moveSpeed;
    }
}
jvralston
  • 1
  • 1
  • What is the `PlayerController`? – Jay Apr 21 '20 at 22:41
  • thanks Jake -- That is the the player essentially -- its an GameObject for an oculus rig, so there are multiple cameras, capsule collider, mesh renderer, and a script I made for keyboard based navigation during testing, all children of the PlayerController. btw, the movement works great when its single step within onTriggerEnter, but doesn't seem to work when its in the Update method. – jvralston Apr 21 '20 at 23:30
  • Maybe you dont really need PlayerController gameobject but a parent above ? It is a little difficult without more information. Could you possibly provide a picture of your hierarchy of gameobject when the game is running? – Skdy Apr 21 '20 at 23:37
  • stack overflow won't let me attach an image, I'm new here, but I appears to have created a link to the image. the script above is a child of the step2 object . – jvralston Apr 21 '20 at 23:45
  • Sorry, what's the difference between `PlayerController` and `Player`? does the `PlayerController` object actually move or is it more of an abstract controller class? – Jay Apr 22 '20 at 12:32
  • Yeah, its really just a container for everything related to the player, so in my mind, same thing - I could have just as easily called PlayerController --> Player, but PlayerController was in the sample framework script I started hacking to death. I also tagged the PlayerController with 'Player', and then I use GameObject variable 'player' to refer to it too. – jvralston Apr 22 '20 at 12:44

1 Answers1

0

I believe your problem may be that you are using OnTriggerEnter() to set the position you want your player to move to, this will be called on the frame your player enters your trigger but then won't be called again until the player left and re-entered...
If you instead use OnTriggerStay() - something like

void Start(){ // this lookup can be expensive so lets only do it once
    player = GameObject.FindWithTag("Player");
    playerController = GameObject.Find("PlayerController");
}

void OnTriggerStay(Collider other){ // this is called once per frame that a collider remains in a trigger
    if(other.gameObject.tag == "Player"){ // just in case anything else ever enters the collider
        currentPos = playerController.transform.position;
        currX = currentPos.x;
        currZ = currentPos.z;
    }
}

void FixedUpdate(){ // it's generally advised to move objects in fixed update
    player.transform.position = new Vector3(currX, 3.4f, currZ) * Time.fixedDeltaTime * moveSpeed;
}
Jay
  • 2,553
  • 3
  • 17
  • 37
  • This should solve the specific problem you are asking but I do worry that your approach might be a little flawed and will probably require more testing and a little re-working. I didn't feel it my place to massively restructure your code however, especially as I don't actually know your use case etc. best of luck and I hope this helps. – Jay Apr 22 '20 at 12:49
  • 1
    I'll try this today. Yeah, no need to rewrite the whole thing -- its a mess. Back at both of you later with results. thanks much! – jvralston Apr 22 '20 at 12:53
  • ``` void Start() { player = GameObject.FindWithTag("Player"); playerController = GameObject.Find("PlayerController"); } void OnTriggerStay(Collider other) { if (other.gameObject.tag == "Player") { currentPos = playerController.transform.position; currX = currentPos.x; currZ = currentPos.z; } } void FixedUpdate() { player.transform.position = new Vector3(currX, 3.4f, currZ) * Time.fixedDeltaTime * moveSpeed; }``` – jvralston Apr 23 '20 at 01:29
  • There's my code, minus comments and declarations, and got weird results - basically even before I 'step' onto the object with which this script is associated, it resets position of player to (0, .2, 0), where the start position when app launches is ~(-11, 3, -2), as if that script ran from the beginning somehow, and as if the currX and currZ assignments made it into the mix. Any thoughts on diagnosis or troubleshooting would be greatly appreciated. Thanks! – jvralston Apr 23 '20 at 01:35
  • Yes, this is what i was getting at, you are setting the value of player directly by a separate script. if you add a boolean that will hold if the player is stood on the platform and only update the position if this is true. To be honest a player controlling script that can handle moving platforms can be very difficult to program - i would suggest looking up a tutorial on this. – Jay Apr 23 '20 at 15:56