Hey everybody,
I am new here and would appreciate your help!
I am building some architecture by using almost only the EscalatorPro asset: EscalatorPro | Animation Tools | Unity Asset Store
It’s fun because almost any Prefab can be inserted as a “stair” and the scalatorPRO-script manages all instancing and movement of the stairs.
However I wish to insert an FPS controller which then can be transported by the the escalator without having to be moved manually with “WASD”.
I tried this approach and added the “Attach Player Script” to each and everey instance of a stair produced by the escalatorScript:
It works as so far that my FPS controller (from standard assets package) is becoming a child of each step but still it doesn’t get transported. I don’t know why. Maybe it has something to do with how the escalator script actually works (I am the new to understand this script yet).
Maybe there’s even a much simpler solution to this than the one I see? Is there maybe an FPS controller which will simply do the trick without having to write extra code etc.?
Thanks,
Chris
Hard to say without some more information.
Keep in mind reparenting something does NOT move it. You have to then move it yourself… any object can be a parent of any object anywhere else.
Also, I haven’t seen what the FPS controller does inside recently, but it might keep track of position internally in variables instead of via the Transform. In this case you need somehow to tell it that you’ve moved so that its internal state is updated.
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
- is this code even running? which parts are running? how often does it run?
- what are the values of the variables involved? Are they initialized?
Knowing this information will help you reason about the behavior you are seeing.
One handy thing is to call Debug.Break() in code at the moment something interesting happens, like when you hop on and reparent. This will pause the editor and let you study where everything is in the scene.
Thanks for the motivating response, @Kurt-Dekker !
My code currently really isn’t more than that:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAttach : MonoBehaviour
{
public GameObject Player;
public bool attached = false;
private void OnTriggerEnter(Collider other)
{
if(other.gameObject == Player)
{
attached = true;
Player.transform.parent = transform;
Debug.Log(attached);
// Player.GetComponent<Rigidbody>().isKinematic = true;
}
}
private void OnTriggerExit(Collider other)
{
if(other.gameObject == Player)
{
attached = false;
Player.transform.parent = null;
Debug.Log(attached);
// Player.GetComponent<Rigidbody>().isKinematic = false;
}
}
}
And according to the debug-messages, everything works just as planned. Except, the position of the player doesn’t get changed. I’ve tried a couple of FPS controllers as well (including all FPSs from standards and more.). In fact, if I am using the currently commented-out script (“is kinematic”) the “transportation” works just as desired except my FPS is locked (and unable to leave the stair again). I suppose that’s a dead end regarding my intention.
As you proposed @Kurt-Dekker I guess I’d have to update the FPS position “manually” by adding a script to the FPS. How would I do that? I’ve tried this: Making Unity Standard Asset FPS Controller work with moving platforms - Questions & Answers - Unity Discussions
But I am unable to make it apply to my scenario.
I’d Appreciate your help!
best,
Christian
Or perhaps by turning it off (disabling the FPS script?). Think above the problem: We know that if you put a cube and parented it to a moving platform without any other scripts, we know the cube would move with the platform.
Something is causing this to NOT happen to your player. What is it? Is something deparenting? Is something else moving? Only you can instrument your precise setup and identify what is going on.
Try destroying the FPS controller (in code) at the moment you jump on the cube. Does the player start moving? Great! Now you learned something. Obviously that’s not a solution, but you gained insight: you know it’s something in the player FPS.
If the player STILL doesn’t work when you destroy the FPS controller upon leaping on a platform, well we know we can stop looking there and look elsewhere. Next try destroying something else at the moment you leap on the platform (obviously something that is in the scene). Press Pause and look around the scene while the game continues to run to find other candidates to try destroying in code.
Simplify everything down: the ground and one barely-moving platform, jump on, and start using Debug.Log() to print out the players position EVERYWHERE… in the platform code, in the player, wherever you think it might be changing.
This is how you delve down to get to the bottom of the eternal programming question: “what is changing my data?!!!”
You will find it.
@Kurt-Dekker I really appreciate the way you think about that problem! That definitely keeps me going.
I have been comparing two different FPS in a stripped down setup. Both are part of Standards Assets:
- “FPSRigidbody” stays at the same position regardless if it’s FPS Script is deactivated or not. Hence its interaction is only dependent on its colliders and rigidbody. Having your “cube-thought-experiment” in mind, I changed the capsule collider to a box collider and it actually works quite well for my purpose without having to use code at all (child/parenting-stuff etc.)!
However, the second, “FPSController” handles interaction only with code in combination with a “character controller component”. I tried to “destroy” the code by manually commenting out lines of code. I was able to trace down some lines which are responsible for the behaviour I want to avoid but I don’t understand them yet. Commenting out the marked line results in the FPS being properly transported by the stairs but by loosing the ability to move or jump (thus to ability to leave the stair again).
private Vector3 m_MoveDir = Vector3.zero;
private CharacterController m_CharacterController;
private CollisionFlags m_CollisionFlags;
[...]
// comment out here
m_CollisionFlags = m_CharacterController.Move(m_MoveDir*Time.fixedDeltaTime);
[...]
// "m_CollisionFlags" is only referenced by the following code-excerpt:
private void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
//dont move the rigidbody if the character is on top of it
if (m_CollisionFlags == CollisionFlags.Below)
{
return;
}
if (body == null || body.isKinematic)
{
return;
}
body.AddForceAtPosition(m_CharacterController.velocity*0.1f, hit.point, ForceMode.Impulse);
}
Assuming, I figured out how to alter/“destroy” the latter code to fit my purpose. How could I implement that it only happens when jumping on the cube and resumes after leaving, like @Kurt-Dekker suggested:
Thanks a lot!