How to rotate RigidBodyFPSController (C#)
HI all,
I have a portal mechanic in my project. I want it so when the Player collides with the portal, not only does it send them out through the other portal, but it also spins them 180 degrees to the left/right.
I have some code working. The portal teleport function works perfectly, but the rotating the player part is the issue.
Say I'll walk into the BLUE portal in a North direction, When I hit that BLUE portal, I get sent out the RED portal. I do turn 180 degrees for half a second, but then the character auto-spins itself back in the direction I entered the BLUE portal.
How would I rectify this spin problem? Pretty new to C# so it's a learning process for me.
Photos attached of code and a quick video of the auto-spin problem. IMGUR LINK =: https://i.imgur.com/SV7HiRF.png
Cheers all.
Sure, I'll upload it to I$$anonymous$$GUR https://i.imgur.com/SV7HiRF.png
hard to say, that script isnt the problem, somewhere else you must be applying forces to the rigidbody of the player, can you share the player script¿? since somewhere else you must be applying a force.
Answer by ray2yar · Feb 18, 2019 at 11:38 AM
When you copy code - use the "Coder Sample" button, and then copy and paste.
Anywho, your code to rotate should work. So, the problem is elsewhere. I suspect it's in your playerMotor. The user is pressing forward but in the instant you teleport , forward is toward the blue portal. A few things you could do:
First, instead of having the portal change the player's orientation with a rotation, have it tell the playerMotor to use the rigidbody to do this... SendMessage will work fine for this. On the player motor perform your rotation and disable control input for a split second to allow the player to reorient themselves.
Second thing to try: make your rotation more "generic" ... here's what I mean... let's assume you want the player to face in the forward direction of the portal regardless of which angle they came in from (they could hit from the sides, in which case you probably don't want to spin 180 degrees). So instead, set the rotation to be the forward direction of the portal (or -1* it if they are facing the otherway).
if(other.tag == "Player")
{
other.transform.forward = transform.forward;
}
Also, you probably don't need a reference to the player object.
I've added transform.forward to my portal teleport script, so next step is to "control player motor"
Where in the RigidbodyFirstPersonController where would I implement some code so when I hit a portal, it stops control input for a second and rotates the character in the forward direction of the portal?
Cheers
So you will either set the rotation using transform OR with the rigidbody; not both.
This code SHOULD do what you're looking for:
//put on your portal
void OnTriggerEnter(Collider other)
{
if(other.tag == "Player")
{
other.Send$$anonymous$$essage("PauseInput", transform.rotation);
}
}
//all of this goes on the script that controls the player
//reference to the rigidbody
public Rigidbody RB;
//called by the portal by sendmessage, assigns a rotation
public void PauseInput(Quaternion rot)
{
RB.rotation = rot;
RB.is$$anonymous$$inematic = true;
Invoke("ResumeInput", 0.1f);
}
void ResumeInput()
{
RB.is$$anonymous$$inematic = false;
}
Here is my current code now. I can see that the code toggles "Is $$anonymous$$inematic" in the RigidbodyFPSController, and it stops me moving once I enter the portal for a second before resu$$anonymous$$g controls, but no rotation of the player actually happens. Any last help would be highly appreciated :)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StepThroughPortal : $$anonymous$$onoBehaviour
{
public GameObject otherPortal;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter(Collider other)
{
Debug.Log("Hit Portal");
if(other.tag == "Player")
{
other.transform.position = otherPortal.transform.position + (otherPortal.transform.forward * 3);
other.Send$$anonymous$$essage("PauseInput", transform.rotation);
}
}
//reference to the rigidbody
public Rigidbody RB;
//called by the portal by sendmessage, assigns a rotation
public void PauseInput(Quaternion rot)
{
RB.rotation = rot;
RB.is$$anonymous$$inematic = true;
Invoke("ResumeInput", 0.1f);
}
void ResumeInput()
{
RB.is$$anonymous$$inematic = false;
}
}
Try it with the transform ins$$anonymous$$d. You might also set all forces and velocities to the rigidbody to zero
I keep getting this error in the console whenever I go through a portal:
Send$$anonymous$$essage PauseInput has no receiver! UnityEngine.Component:Send$$anonymous$$essage(String, Object) StepThroughPortal:OnTriggerEnter(Collider) (at Assets/StepThroughPortal.cs:27)
Your answer
Follow this Question
Related Questions
Try part of C# not being Read 1 Answer
Trying to make a Parkour Platformer! 0 Answers
Why won't my model rotate up on X axis? 1 Answer
OnTriggerExit does not work 0 Answers
Help with Script 0 Answers