- Home /
Trying to freeze FPS character to one point for a specific amount of time
Hello! So, I have a problem that has been driving me crazy. I am trying to create a simple scene where the player enters a dungeon, and is frozen in place looking at the enemy speak for about five seconds. Afterwards, the player would be unlocked from any restraints. I have tried using the freeze rigidbody method, but the player would just run in place. The script I have is also on the FPS controller, and it has a sword and shield attached, so I can't disable it.Using this script here will partially freeze the player, letting them sprint and walk in place. Also, when the five seconds is up, the camera will jerk wildly for a few seconds before going off to the right, and everything returns to normal. Any help would be greatly appreciated! using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityStandardAssets.Characters.FirstPerson;
public class FPSplacement : MonoBehaviour {
private GUIruntime2 guiruntime2;
public GameObject FPSController;
public Transform target;
public GameObject spawn;
// Use this for initialization
void Start () {
Scene currentscene = SceneManager.GetActiveScene();
string sceneName = currentscene.name;
guiruntime2 = FPSController.GetComponent<GUIruntime2>();
}
// Update is called once per frame
void Update () {
if (SceneManager.GetActiveScene() == SceneManager.GetSceneByName("SimpleSword2part2") && guiruntime2.roar == true)
{
StartCoroutine(Waiting());
}
}
IEnumerator Waiting()
{
transform.position = spawn.transform.position;
//transform.LookAt(target); is to make the player look at the NPC.
transform.LookAt(target);
//target is the enemy
yield return new WaitForSeconds(5);
//To make the character look at the NPC after the timer.
transform.LookAt(target);
//guiruntime2 is the dialouge that the NPC has on screen. After five seconds it becomes disabled.
//when guiruntime is finished, it has a bool that is set to false.
guiruntime2.roar = false;
}
}
I mainly develop 2D, and write my own controllers. Had to take a quick peak at how the FPSCC works. It looks like you still read inputs, then dictate what the controller should do. For a precise answer, I imagine it'd be best if you also included your animation code, and any code that accepts input and acts upon it (moving your player, moving your camera, firing/using a weapon).
For a less precise answer, having a boolean value that prohibits the reading of input will get you a long way.
Player.instance.CanControl(false);
From what I can tell, it looks like you're actively trying to counteract other behaviors, rather than just stopping them from acting.
I ended up doing something like that, and just disabling the FPS script. I am sorry that it wasn't super clear, that was something I was afraid of. Thank you for your response, I really do appreciate it- and I'll have to keep your solution in $$anonymous$$d in case I need it later on :)
Answer by browne11 · May 25, 2018 at 11:52 PM
Your coroutine appears to be running in the update sequence which isn't a great idea. However you can still make it work but you need to use another variable inside the update function preventing it from getting called more then once; which appears to be the issue.
This isn't the most elegant way of doing it but it will solve your issue of the coroutine getting activated multiple times.
public class FPSplacement : MonoBehaviour {
private bool freeze;
private GUIruntime2 guiruntime2;
public GameObject FPSController;
public Transform target;
public GameObject spawn;
// Use this for initialization
void Start () {
Scene currentscene = SceneManager.GetActiveScene();
string sceneName = currentscene.name;
guiruntime2 = FPSController.GetComponent<GUIruntime2>();
}
// Update is called once per frame
void Update () {
if (SceneManager.GetActiveScene () == SceneManager.GetSceneByName ("SimpleSword2part2") && guiruntime2.roar == true) {
if (freeze != true)
{
StartCoroutine (Waiting ());
}
}
}
IEnumerator Waiting()
{
freeze = true;
transform.position = spawn.transform.position;
//transform.LookAt(target); is to make the player look at the NPC.
transform.LookAt(target);
//target is the enemy
yield return new WaitForSeconds(5);
//To make the character look at the NPC after the timer.
transform.LookAt(target);
//guiruntime2 is the dialouge that the NPC has on screen. After five seconds it becomes disabled.
//when guiruntime is finished, it has a bool that is set to false.
guiruntime2.roar = false;
freeze = false;
}
}
Thank you for the reply! I tried your script, but it didn't work for me. Thank you for providing it though, I really do appreciate it. But I don't think the issue is the coroutine being called more than once- I have a condition that says that guitime2.roar has to be equal to true before the coroutine actually runs, and at the end of the coroutine it sets it to false. But, I managed to remedy the problem by just disabling the FPS controller script. Thank you again though for your answer!
If you look closely, the roar is set to true it then enters the update sequence and starts the coroutine which takes 5 seconds before you finally turn it to false. So technically you can still start a new coroutine during the 5 seconds it takes to turn it off.
The update is run every .02 seconds give or take the speed of your computer so you're starting a new coroutine on top of the already running ones. I would guess you have close to 250 of them running.
Your answer
![](https://koobas.hobune.stream/wayback/20220612163431im_/https://answers.unity.com/themes/thub/images/avi.jpg)