I have an issue in my project at the moment, after a player finishes a level a new scene is loaded but I'm not able to move the mouse cursor. To begin with it wouldn't show either so I added the code;
Cursor.visible = true;
Now the mouse cursor is visible but I still can't move it from the center of the scene. Any help or advice would be appreciated.
You may need to reset lockState to None as well:
Cursor.lockState = CursorLockMode.None;
See Cursor.lockState documentation.
You can also do a script that will call it once on the void Start() an example that will work.
Place the script anywhere or on the canvas or create an empty Object and place this script on it.
void Start ()
{
Cursor.lockState = CursorLockMode.None; Cursor.visible = true;
}
That will work once you leave the scene and go back to it using the script above it will kick in, and Cursor will work and begin to interact with the loaded scene.
It shouldn't be that way, but it works. Cheers!
WP
Related
I am new to C# and Unity and I'm trying to figure out how to make an animation for an object in unity play when I press a key but I can only make the animation play once, and then it is broken and doesn't work. (I am trying to make an FPS game)
The code I have right now looks like this:
void Start()
{
gameObject.GetComponent<Animator>().enabled = false;
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
gameObject.GetComponent<Animator>().enabled = true;
}
}
When I press run and left click, the animation triggers and does as it is supposed to but when I try to do it again, the animation doesn't work. Can anybody help me change this code so that the animation will work and play every time the button is pressed?
I am assuming your animation is non-looping as if it was looping it would already play back into itself when it is over.
One quick note I would have with your code is do not use GetComponent in an Update function as it is quite costly. An easy way to get an animation state to reset is to enable and disable it, however I am assuming you want to have more animations than shooting. You would want to look into what is called an Animation Tree or a Blend Tree and add States to your animation. Examples of states would be an Idle, Walk, Run, Shoot, Crouch, etc. I would consider researching Animation Trees and Blend Trees to get a full animation cycle in.
Once you get a State machine working, I would have the enter go to an Idle state, then either set a transition Bool or directly switch the animation in code.
// when you serialize a private field, it will appear in
// the inspector so you can drag in the reference in the editor
[SerializeField] private Animator anim = null;
private void Start()
{
anim.enabled = false;
}
private void Update
{
if(Input.GetButtonDown("Fire1")
{
Shoot();
if(!anim.enabled)
anim.enabled;
else
anim.Play("AnimationStateName", -1, 0f);
}
}
I have not tested the code, but I believe this would work with your setup. I would still strongly advise to not do this and look into Trees. After implementing the tree, instead of calling using the enabled, just use the line anim.Play("AnimationStateName", -1, 0f) or you can do anim.SetBool(isAttacking, true) if you set your state to transition from Idle/Run/Walk/etc. to Attacking when the isAttacking bool is set to true.
I found a video that might help you out. I do not want to post a full explanation to animation states and blend trees, just point you in the right direction to a better approach.
The cursor disappears when making a single click, like so:
How to reproduce:
get the Game Jam Menu template:
https://www.assetstore.unity3d.com/en/#!/content/40465
Add another scene with an FPS controller imported from the standard
assets.
Tick the "change scenes" in the UI -> start options component.
Press escape and touch the slider, any single click will make the
cursor disappear.
It looks like this: https://imgur.com/a/hefmP
If I tick off the mouse look -> lock cursor in the FPS controller then this doesn't happen, but I also see the cursor in my FPS game.
I tried to add Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; and the opposite when pausing and unpausing but it doesn't help. Probably because the MouseLook.cs is also updating them in:
I'd rather not couple the FPSController and the pause menu and they're also in different scenes.
So how else can I unlock the cursor when entering the pause menu? Is there an event pattern that can be used here?
It also darkens the scene, but that's for another question.
It's been modified by the MouseLook script which is used in the FirstPersonController script. One solution is to modify the MouseLook script but a simple Asset update would kill that modification.
A proper solution to this problem is to disable the FirstPersonController script when you open up any menu and then enable it back when you close that menu. Also, when you disable it, manually set Cursor.lockState to None and set the cursor to visible.
Below is a simple function that will handle that. Each of your menu open and close button should be linked to the function below. When you call it, pass false to it with the open button and true to it with the close button:
void enableFPS(bool enable)
{
GameObject fpsObj = GameObject.Find("FPSController");
FirstPersonController fpsScript = fpsObj.GetComponent<FirstPersonController>();
if (enable)
{
//Enable FPS script
fpsScript.enabled = true;
}
else
{
//Disable FPS script
fpsScript.enabled = false;
//Unlock Mouse and make it visible
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
I want to freeze gameobject after dragging it to the right position using OnMouseDrag
There is a lot of way doing that. I assume you move everything from script, so wherever you update the position of an object, you can stop it from updating with a simple if statement.
In pseudo code:
void Update(){
if(isInRightPosition(yourGameObject) == false){
you are free to update the position
}else{
do nothing and the object will remain in same position;
}
}
bool isInRightPosition(yourGameObject){
return yourConditionalExpression;
}
if that doesn't work, because you are using some other tool to update the position of your object you can also save the right position for the object locally when it is placed well, and just update it's position on every frame in the FixedUpdate function if it involves physics or in the Update function if it does not So even if the user would like to move it, your code will reset it.
So your Update function would be similar to that
C# code now:
Vector3 lockedPosition = new Vector3(myX, myY, myZ);
void Update(){
Rigidbody rigidbody = GetComponent<RigidBody>();
if(isInRightPosition(yourGameObject) == true){
rigidbody.position = lockedPosition;
}else{
/*let the player move the object*/
}
}
Also you can apply this logic in the event handler that you use if you want.
Thanks for reading. I tried posting this on unity answers, but it's been 24 hours and it's still not out of moderation, so maybe I'll have better luck here.
Background
I am very new to unity and know I must be missing some critical piece of knowledge to tie this together. I've created a blank game with some placeholder terrain and added a main camera to the 3d orthographic scene. I would like the user to be able to move the camera along a parallel plane to the ground.
What I've Done
I've added a starter camera codebehind I found online along with an event system, rigid body, ray caster, and a bunch of other things I saw online for this sort of thing. All of these components are in the same layer.
The Problem
My camera script's update method is hit when I put that in for testing but it doesn't receive any other events even though it implements the appropriate interfaces. I'm guessing I have something blocking the input from hitting the script or I do not have a component I need in order for those events to fire.
I'm testing on desktop for now but I want this to run on mobile (although from what I've read the events I'm subscribing to should be universal). Can anyone spot any oversights or deficiencies in my setup so far? Here are some screenshots.
Thanks!
My Setup
Edit: by request, here is the camera script I'm using. I know it doesn't do what I want yet but the issue I'd like to tackle right now is why it doesn't seem to be wired up correctly. Like I said, if I put an update method in here it is hit but none of my other logs are hit.
using UnityEngine;
using UnityEngine.EventSystems;
// The touch is in 2D but the scene is in 3D, so touch.x => scene.x, touch.y => scene.z, and nothing change (0) => scene.y since y is up
public class TouchCamera : MonoBehaviour,
IPointerDownHandler,
IDragHandler,
IPointerUpHandler
{
private Vector3 prevPointWorldSpace;
private Vector3 thisPointWorldSpace;
private Vector3 realWorldTravel;
private int drawFinger;
private bool drawFingerAlreadyDown;
public void OnPointerDown(PointerEventData data)
{
Debug.Log("Pointer down");
if (drawFingerAlreadyDown == true)
return;
drawFinger = data.pointerId;
drawFingerAlreadyDown = true;
prevPointWorldSpace = data.pointerCurrentRaycast.worldPosition;
// in this example we'll put it under finger control...
GetComponent<Rigidbody>().isKinematic = false;
}
public void OnDrag(PointerEventData data)
{
Debug.Log("Pointer drag");
if (drawFingerAlreadyDown == false)
return;
if (drawFinger != data.pointerId)
return;
thisPointWorldSpace = data.pointerCurrentRaycast.worldPosition;
realWorldTravel = thisPointWorldSpace - prevPointWorldSpace;
_processRealWorldtravel();
prevPointWorldSpace = thisPointWorldSpace;
}
public void OnPointerUp(PointerEventData data)
{
Debug.Log("Pointer up");
if (drawFinger != data.pointerId)
return;
drawFingerAlreadyDown = false;
GetComponent<Rigidbody>().isKinematic = false;
}
private void _processRealWorldtravel()
{
Debug.Log("Updating camera position");
Vector3 pot = transform.position;
pot.x += realWorldTravel.x;
pot.z += realWorldTravel.y;
transform.position = pot;
}
}
Final Edit for the Solution
Thank you very much to Juan Bayona Beriso for helping me in chat with this configuration. Here is what we ended up with that now works:
The camera object has a Rigidbody and Physics 2D Raycaster attached to it. The scene now has a new Canvas object with a Graphics Raycaster (blocking mask set to everything and blocking objects set to none) and an event system with the standalone input module enabled. That canvas also has a child UI object that covers the screen and has the camera script attached. As a curiosity, it required a text component in order for the script to start receiving the events -- this only made a difference when the Raycast Target option was selected. Screenshots below.
I think you are misusing the EventSystem, OnPointerDown, OnDrag and all those functions, they are called when you have a PhysicsRaycaster in your Camera object and you press or drag over an UI Element or and object with a collider.
In your code you don't have any of these, you have a camera so you are not actually pointer down over it or dragging on it.
You have two options:
Either put this script in a plane with a collider or GUI element that is inside the camera and moves with it, or use Input.GetMouseButtonDown, Input.GetMouseButtonUp in the Update function
I'm VERY new at programming in unity and it really is not my forte.
But I really need help with this.
I need help making a code that will change places with two game objects (8 in total all need to be able to switch with eachother) I want to use the mouse left key click to work.
All I got this far is:
void OnMouseDown ()
{
transform.position = otherObject.transform.position;
}
but this doesn't do anything.. please help! :)
For OnMouseDown() message to work you have to attach a Collider component. Go to Component->Physics menu and select a collider that fits your object. Most likely you want to use a Box Collider.
To switch objects you can do this:
void OnMouseDown ()
{
Vector3 temp = transform.position;
transform.position = otherObject.transform.position;
otherObject.transform.position = temp;
}