I am trying to make a door in my unity game for testing purposes, but I'm finding that my door doesn't shut completely once it has been opened.
This is most of my code for my door
{
unlockedSound.Play();
locked = false;
keyOB.SetActive(false);
StartCoroutine(unlockDoor());
}
if (inReach && doorisClosed && unlocked && Input.GetButtonDown("Interact"))
{
door.SetBool("Open", true);
door.SetBool("Closed", false);
openText.SetActive(false);
openSound.Play();
doorisOpen = true;
doorisClosed = false;
}
else if (inReach && doorisOpen && unlocked && Input.GetButtonDown("Interact"))
{
door.SetBool("Open", false);
door.SetBool("Closed", true);
closeText.SetActive(false);
closeSound.Play();
doorisOpen = false;
doorisClosed = true;
}
if (inReach && locked && Input.GetButtonDown("Interact"))
{
openText.SetActive(false);
lockedText.SetActive(true);
lockedSound.Play();
}
}
IEnumerator unlockDoor()
{
yield return new WaitForSeconds(0.05f);
{
unlocked = true;
lockOB.SetActive(false);
}
}
I have the animations set to properly close the door, I'm unsure of how to move forward with this.
I have even tried isolating the door and suspending it in the air incase something was preventing it from closing properly
Related
im creating an android map game and i cant solve a problem, i have a map and i also have a menu that pops up once i press on a gameobject with a collider. I had a problem that if i would press on that UI menu it would go throught it and it would turn the menu off, because i coded that if i press on another gameobject with a collider it would turn off. I fixed that by making a UI detection script (found it on google), where it draws a raycast from my cursor and detects a gameobject with a specific layer and returns a true or false value.
THE PROBLEM: Right now everything works fine on pc, since i am hovering with my cursor, but if i go on my unity remote once i press on the menu, it still turns off, because i guess its not quick enough to detect that its a UI element?
SOME CODE:
This is a UI Detection code:
public bool isOverUI;
private void Start()
{
UILayer = LayerMask.NameToLayer("MAINMENUCOMPONENTS");
}
private void Update()
{
print(IsPointerOverUIElement() ? "Over UI" : "Not over UI");
}
//Returns 'true' if we touched or hovering on Unity UI element.
public bool IsPointerOverUIElement()
{
return IsPointerOverUIElement(GetEventSystemRaycastResults());
}
//Returns 'true' if we touched or hovering on Unity UI element.
private bool IsPointerOverUIElement(List<RaycastResult> eventSystemRaysastResults)
{
for (int index = 0; index < eventSystemRaysastResults.Count; index++)
{
RaycastResult curRaysastResult = eventSystemRaysastResults[index];
if (curRaysastResult.gameObject.layer == UILayer)
{
isOverUI = true;
return true;
}
}
isOverUI = false;
return false;
}
//Gets all event system raycast results of current mouse or touch position.
static List<RaycastResult> GetEventSystemRaycastResults()
{
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.position = Input.mousePosition;
List<RaycastResult> raysastResults = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, raysastResults);
return raysastResults;
}
This is the menu code:
public UIDETECTIONS UID;
if (UID.isOverUI == true)
{
}
else if (UID.isOverUI == false)
{
if (infoMenuOn == false)
{
if (isCountryClicked == false)
{
isCountryClicked = true;
infoMenuOn = true;
Debug.Log("MENU ON");
}
else if (isCountryClicked == true)
{
isCountryClicked = false;
}
}
else if (infoMenuOn == true && isCountryClicked == true)
{
infoMenuOn = false;
isCountryClicked = false;
Debug.Log("MENU OFF");
}
}
I Should have done more research :D, derHugo gave me a hint, which was kind of an answer.
I found this piece of code which works for android. Works quite the same.
private bool IsPointerOverUIObject() {
PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
return results.Count > 0;
}
With this code you can check if youre clicking over ui elements:
if (IsPointerOverUIObject() == true) // true or false
I am creating this simple 3D game but I'm having an issue with player vs computer mode. I want to be able to play vs 1 to 3 bots and when it's my turn I want the game to wait for me to click, but when it's the bots turn I want to them to auto play. What really happens with my code is that everything goes to auto play. I know the issue is with Update function because Update is called once per frame but I don't know how to fix it. Can you help me? The idea is to use a tracker/counter like i = 0 first. When it's 0 it means my character will play so it should wait for my mouse to be pressed. When it's not 0 it will be bots turn. This is the section of the code. Function veprimetELojtareve is the same as the code inside if(!bota).
private int i = 0;
// Update is called once per frame
void Update()
{
if (!bota)
{
if (Input.GetMouseButtonDown(0)) // Left Click
{
if (hasLanded)
Reset();
RollDice();
}
if (rb.IsSleeping() && !hasLanded && thrown)
{
hasLanded = true;
rb.useGravity = false;
rb.isKinematic = true;
SideValueCheck();
}
else if (rb.IsSleeping() && hasLanded && diceValue == 0)
RollAgain();
}
else
{
if (i == 0)
veprimetELojtareve();
else
{
if (hasLanded)
Reset();
RollDice();
if (rb.IsSleeping() && !hasLanded && thrown)
{
hasLanded = true;
rb.useGravity = false;
rb.isKinematic = true;
SideValueCheck();
}
else if (rb.IsSleeping() && hasLanded && diceValue == 0)
RollAgain();
}
i = (i + 1) % numriLojtareve;
Debug.Log("Vlera e i eshte: " + i);
}
}
I've started learning C# and Unity3D this year and I've come across a problem. I'm loading a new level and the player object gets initialized before the the level has finished loading.
I think I only need to check whether the level is loaded or not before initializing the object. I don't know if I could use LoadLevelAsync. I'm using Unity3D Personal Edition.
My current code:
MasterClient.cs
void Update(){
if(SceneUpdateRequired)
{
Application.LoadLevel(SceneUpdateID);
if (Application.isLoadingLevel == false)
{
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
}
}
}
void CharacterLoginUpdate(){
if (SceneUpdateCompleted == true)
{
GameObject networkPlayerObj = (GameObject)Instantiate(NPlayerObj, PlayerLoginUpdatePosition, PlayerLoginUpdateRotation);
NPlayer networkPlayer = networkPlayerObj.GetComponent<NPlayer>();
networkPlayer.UpdatePlayerInstantiateCompleted(PlayerLoginUpdateNetworkID, PlayerLoginUpdateHP, PlayerLoginUpdateClass, PlayerLoginUpdateLevel, PlayerLoginUpdateName, PlayerLoginUpdatePosition);
PlayerLoginUpdateRequired = false;
}
}
The problem with your code is your are loading level in update where if you dont control the task with booleans you are going to end up with big problems.
your update code should be as follows
void Update(){
if(SceneUpdateRequired)
{
Application.LoadLevel(SceneUpdateID);
SceneUpdateRequired = false;
}
if (Application.isLoadingLevel == false)
{
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
}
}
This way the scene code will try to load level only when you request it to and not every time in update loop as loading levels is heavy.
Another thing is you might encounter one more problem if you need to use
SceneUpdateRequired,SceneUpdateCompleted variables somewhere else the
if (Application.isLoadingLevel == false)
{
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
}
the above part which is in update loop will reset the variables everytime whenever its not loading the level. To prevent this you will have to introduce another boolean flag to stop its update happening everytime. So your code will end up looking like this if you want to prevent everyframe update
void Update() {
if(SceneUpdateRequired){
Application.LoadLevel(SceneUpdateID);
SceneUpdateRequired = false;
}
if (Application.isLoadingLevel == false && StartCheckingLoadLevel){
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
StartCheckingLoadLevel = false;
}
}
void StartLoad() {
SceneUpdateRequired = true;
SceneUpdateCompleted = false;
StartCheckingLoadLevel = true;
}
void CharacterLoginUpdate(){
if (SceneUpdateCompleted == true) {
Debug.Log("Do Something after load");
} else {
Debug.Log("Scene not yet loaded");
}
}
Hope this helps.
I'm making a Snake game on C#, but I'm having a glitch with my keys.
I'm following the exact code found here. http://codesmesh.com/snake-game-in-c/
The error that I get is that... for example if I was going down, if I pressed right and up at the EXACT same time, where i basically press it together, the snake goes up and walks into its own body, killing itself.
This is my keydown section in my code.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
//Space is just to restart the form.
if (e.KeyData == Keys.Space)
{
timer1.Enabled = true;
codesmeshlabel.Text= "";
spaceBarLabel.Text = "";
down = false;
up = false;
left = false;
right = true;
}
if (e.KeyData == Keys.Down && up == false)
{
down = true;
up = false;
right = false;
left = false;
}
if (e.KeyData == Keys.Up && down == false)
{
down = false;
up = true;
right = false;
left = false;
}
if (e.KeyData == Keys.Left && right == false)
{
down = false;
up = false;
right = false;
left = true;
}
if (e.KeyData == Keys.Right && left == false)
{
down = false;
up = false;
right = true;
left = false;
}
}
This sounds like you are changing the direction your snake is traveling to "right", and then setting it to "up" before the snake moves again.
Somewhere in your code I assume you have a game loop that updates the screen every (however long). To prevent this from happening you would need to change your design so that after your game has accepted a direction change (key.left/right/up/down) it waits until AFTER the screen has been updated once to accept a second direction change. This should fix your bug :)
As m.t.bennett pointed out another option would be to check each keypress to see if it is the opposite direction of current travel, and if so ignore it. Could be more elegant.
I made a pop up menu and when it comes up, I don't want to be able to move or look around. The movement part is all good, but when I disable MouseLook, I can still look up and down. How can I fix this? Also, I don't want to freeze the game time because I might add multiplayer later and I don't want it to freeze the game for other players. Any help will be appreciated.
Here's my code:
if(canOpen == true && isOpen == false && Input.GetKeyDown(KeyCode.E)) {
isOpen = true;
canClose = true;
player.GetComponent<FPSInputController>().enabled = false;
player.GetComponent<CharacterMotor>().enabled = false;
player.GetComponent<MouseLook>().enabled = false;
}
else if(isOpen == true && Input.GetKeyDown(KeyCode.E) && canClose == true) {
isOpen = false;
canOpen = false;
player.GetComponent<FPSInputController>().enabled = true;
player.GetComponent<CharacterMotor>().enabled = true;
player.GetComponent<MouseLook>().enabled = true;
}
There are two MouseLook components on Unity's standard First Person Controller: one on the player root that handles rotation about the y-axis (MouseX), and another on the Camera for the x-axis (MouseY).
To enable/disable both, you could use:
foreach(var mouseLook in player.GetComponentsInChildren<MouseLook>())
mouseLook.enabled = false;