Problems with Unity3D Animator controller states - c#

I have an object (a simple card) equipped with the Rigidbody, Collider and Animator components. In particular, Animator performs two simple clips: Cover and Uncover that rotates the card 180 degrees. The first starting from 0 degrees to 180, the second from 180 to 0.
So the clips should cover or uncover the card. The problem is that the card returns to its original state.
For example, the original state of the card is the "uncovered state" so when I click on it to cover it covers as expected. The I register the state "covered" programmatically. However, immediately after the animation ends, it returns to its original state (uncovered). The card now has an internal (C# variable) state as "covered", but I see it to still be uncovered. When I click it again, will be fired the correct animation clip: "uncover".
What should I do to leave it covered at the first click?
I have uploaded here a short clip that shows the behavior of the card, also below find some screenshots that refer to the various views of the IDE that may have useful information. The video clip is uploaded to Dropbox for the while.
The video of the behavior: Dropbox link
The code of the Flip script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Flip : MonoBehaviour {
private Animator anim;
private enum cs_e {covered, uncovered};
private cs_e coveringState;
// Use this for initialization
void Start () {
anim = this.GetComponent<Animator>();
coveringState = cs_e.uncovered;
}
// Update is called once per frame
void Update () {
}
private void OnMouseUp()
{
Debug.Log("Mouse up");
if (coveringState == cs_e.uncovered)
{
anim.Play("Cover");
coveringState = cs_e.covered;
} else {
anim.Play("Uncover");
coveringState = cs_e.uncovered;
}
}
private void OnMouseDown()
{
Debug.Log("Mouse down");
}
private void MouseDrag()
{
Debug.Log("Mouse drag");
}
}
Some screenshots:

Related

C# (Galaga Style Project) - Limit Projectile Prefab Clones based on Hierarchy

I am trying to practice creating a clone of Galaga following the same ruleset as the original. I am currently stuck trying to attempt a limit on the amount of cloned prefabs that can be in the scene at any one time, in the same way that Galaga's projectiles are limited to 2 on screen at any time. I want to make it so the player can shoot up to two projectiles, which destroy after 2 seconds or when they collide (this part is functioning), followed by not being able to shoot if two projectile clones are active and not yet destroyed in the hierarchy (Not working as I can instantiate projectiles over the limit of 2).
I have combed through Google for about 3 hours with no solutions that have worked for me, at least in the ways that I had attempted to implement them.
Thank y'all so much for the help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerController : MonoBehaviour
{
public float moveSpeed = 1.0f;
public playerProjectile projectile;
public Transform launchOffset;
public int maxBullets = 0;
private GameObject cloneProjectile;
public Rigidbody2D player;
// Start is called before the first frame update
void Start()
{
player = this.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
MovePlayer();
PlayerShoot();
}
public void MovePlayer()
{
player.velocity = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")) * moveSpeed;
}
public void PlayerShoot()
{
if (Input.GetKeyDown(KeyCode.Z))
{
var cloneProjectile = Instantiate(projectile, launchOffset.position, launchOffset.rotation);
maxBullets++;
if (maxBullets >= 3)
{
Destroy(cloneProjectile, 0.1f);
maxBullets --;
return;
}
}
}
}
You could change the logic up a bit. An instance of the playerController class is active as long as the game is active, so it will know and retain the value of 'maxBullets' until you die or exit the program.
So instead, every time you click "z", the first thing you should do is run the check. If the current amount of live projectiles equals the maximum, have the logic 'return' and exit out of the method.

On Mouse Click for "OnTriggerStay" to Add Score, Adds More Than Set Amount

Short and simple, object drops into trigger object, I click, score goes up. Score is set to +1, adds +2 to +5, no reasonable explanation (script and video provided)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Score : MonoBehaviour
{
public int currentScore;
public Text displayScore;
public int addScore;
void OnTriggerStay ()
{
if (Input.GetMouseButtonDown(0))
{
currentScore += addScore;
}
}
void Update ()
{
displayScore.text = currentScore.ToString();
}
}
Video, goes to Youtube
first of all, what exactly is calling the OnTriggerStay() function, because that is not the Unity function it should be like this:
void OnTriggerStay(Collider col)
{
if (Input.GetMouseButtonDown(0))
{
currentScore += addScore;
}
}
also note that if you use OnTrigger the ball must have a Rigidbody, other than that GetMouseButtonDown(0) should work as expected and worked fine for my tests.
My only explanation here is that the other script or any script changes currentScore, you can test that by setting the var private.
Edit:
i think i know your problem, i presume that multiple collider trigger the function so it is called multiple times per frame, since it's the same frame Input.GetMouseButtonDown(0) is true for each collider.
You should therefore add a check to the if case
if(Input.GetMouseButtonDown(0) && col.name.Equals("Yoyo")){
...
}
i presume that the ball is called yoyo ;)

Activating animation when within radius

I am trying to create a script for my enemy turret, but it is not going well. I have a couple animations of the turret being activated and deactivated. What I need is that based on the distance from the player, it plays either animation. So once it moves inside the detection radius it plays the activation animation and once it is outside it plays the deactivation animation. Most of the other ways I try require me to create an Animation Controller, which I have little experience in using. I want a simple way to play one animation once it is inside and play a different one when it is outside. I think there was a way to store the animation clip in the script, and then play it. I have attached my current script, so you know what I mean.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyTurret : MonoBehaviour
{
public GameObject Player;
public float DistanceToPlayer;
public float DetectionRadius = 75;
// Start is called before the first frame update
void Start()
{
Player = GameObject.FindGameObjectWithTag("PlayerTank");
}
// Update is called once per frame
void Update()
{
DistanceToPlayer = Vector3.Distance(transform.position, Player.transform.position);
if (DistanceToPlayer<=DetectionRadius)
{
Debug.Log("Within Radius");
}
if (DistanceToPlayer >= DetectionRadius)
{
Debug.Log("Outside Radius");
}
}
}
Calculating and checking the distance of the player for every update() is not ideal. It will work, but it will do more work than it needs to when the player isn't even near it. Its not efficient.
What you may want to do if your player is a Rigidbody, is add a SphereCollider to the turret, set isTrigger=true, set the radius to be your detection radius, and handle the OnTriggerEnter() and OnTriggerExit() events to play or stop animations.
You can also add two public Animiation objects to the script, drag and drop your animations in the editor, then you can use animation.Play() and .Stop() etc. to control the animations.
Something similar to this. Not tested fully, but you can get the idea.
public float detectionRadius = 75;
public Animation activateAnimation;
public Animation deactivateAnimation;
void Start()
{
SphereCollider detectionSphere = gameObject.AddComponent<SphereCollider>();
detectionSphere.isTrigger = true;
detectionSphere.radius = detectionRadius;
detectionSphere.center = Vector3.zero;
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "PlayerTank")
{
activateAnimation.Play();
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "PlayerTank")
{
deactivateAnimation.Play();
}
}
Your animations must not loop otherwise you will have to add more logic to check if animation.isPlaying and do your own animation.Stop() etc.

I'm really struggling to pass the Oculus VRC TestSubmitWhenNotVisible test

I'm stuck on the last test for my app before submission to the Oculus store. I've tried all sorts with no avail. I need to do is pass the frames when not visible test.
Effectively, the app needs to go into pause mode when the user clicks the menu button on the oculus touch controller.
I need to stop all frames submitting from Unity. For example, things I've tried, turn off cameras, audio, ovrplayercontroller etc but frames being submitted when the menu button is pressed on the rift so it would appear to freeze the application.
I've tried disabling cameras in a foreach loop, disabling the player gameobject, ovr controllers all sorts.
I have a gameobject with a script attached to try and detect when the test will fire based on the HMD losing tracking.
Here's where I'm currently at (gone back to the basics again), any help would be greatly appreciated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HMDCheck : MonoBehaviour
{
public GameObject OVRCameraRig;
private void Update()
{
if (!OVRManager.isHmdPresent)
{
OVRCameraRig.SetActive(false);
Time.timeScale = 0f;
}
else
{
OVRCameraRig.SetActive(true);
Time.timeScale = 1f;
}
}
}
Additionally their docs say the test performs this action:
TestSubmitFramesWhenNotVisible
Tests if your app stops submitting frames when the Universal Menu is open.
Note :
My most recent command line response for the test is the following output :
Starting TestSubmitFramesWhenNotVisible
Waiting for the application to run for 5 seconds before testing begins...
Starting test...
Requesting the void...
Number of texture swap chains committed when visible 68
Number of texture swap chains committed when not visible 4
ERROR: Committed a texture swap chain (called ovr_CommitTextureSwapChain) when application not visible
Please refer to VRC Guidelines:
https://developer.oculus.com/distribute/latest/concepts/vrc-pc-input-1/
Cleaning up...
Test FAILED
To get around it, I created a script with public gameobjects. I then dragged my player into the slots inside Unity but left the camera on the scene alone. Here's a screenshot and the code. I initially added the camera to turn off frames sending but Oculus rejected it as it froze in the background upon pressing the menu button.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HMDCheck : MonoBehaviour
{
public GameObject target, scripts, LocalAvatar;
private void Update()
{
if (!OVRManager.hasVrFocus || !OVRManager.isHmdPresent || !OVRManager.hasInputFocus)
{
//target.SetActive(false);
scripts.SetActive(false);
LocalAvatar.SetActive(false);
Time.timeScale = 0f;
AudioListener.pause = true;
}
else
{
//target.SetActive(true);
scripts.SetActive(true);
LocalAvatar.SetActive(true);
Time.timeScale = 1f;
AudioListener.pause = false;
}
}
}
I have almost the same code, but this detects the Universal Menu correctly and does freeze the output, but it still won't pass the test. I think it may pass if you disable splash screens, but can't know since I have the free version of Unity.
Edit: I saw your answer Diego, but cannot comment. Did your action resolve your original question? And what license do you have for Unity?
Camera cam;
bool bPause = false;
void Update()
{
//install 'Oculus Integration' for this to work
bool bPauseNow = !(OVRManager.hasInputFocus && OVRManager.hasVrFocus);
//pause state change
if (Camera.main != null) cam = Camera.main;
if (bPause != bPauseNow)
{
bPause = bPauseNow;
if (bPauseNow)
{
Time.timeScale = 0.0f; //stops FixedUpdate
//Update keeps running, but
// rendering must also be paused to pass vrc
cam.enabled = false;
}
else
{
Time.timeScale = 1.0f;
//
cam.enabled = true;
}
}
//...
}
I am using the "Oculus XR Plugin", and got this issue,
but I found that the results of the "VRC Validator" are not so accurate,
then I submitted the App for review and passed the test.

Send player position to another player to move him in multi player game using Unity Photon

I follow the steps of PUN basic tutorial.
For now I reach to a part of what I want Send my position in the current time to another player with me in the room to move him. I can print my position each time I update it , what I need is to know how I can send position to another player to move him.
Let's say I have a desktop player and when I move him this translation moving the player on mobile.
And how I stop instantiate object on mobile, I just want to deal with the instantiated object on desktop.
I am using unity and Photon Network SDK.
Here is the code I used
using UnityEngine;
using System.Collections;
public class NetworkCharacter : Photon.PunBehaviour {
private Vector3 correctPlayerPos;
void Update()
{
if (!photonView.isMine)
transform.position = Vector3.Lerp(transform.position, this.correctPlayerPos, Time.deltaTime * 5);
photonView.RPC ("PrintPosition", PhotonTargets.All, transform.position);
}
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
// We own this player: send the others our data
stream.SendNext(transform.position);
}
else
{
// Network player, receive data
this.correctPlayerPos = (Vector3)stream.ReceiveNext();
}
}
[PunRPC]
void PrintPosition(Vector3 pos)
{
Debug.Log (pos);
//I need to send position coordinates to the other device
}
}
The other class of establish multiplayer environment:
using UnityEngine;
using System.Collections;
public class NetworkManager : Photon.PunBehaviour {
// Use this for initialization
void Start () {
PhotonNetwork.ConnectUsingSettings ("0.1");
//PhotonNetwork.logLevel = PhotonLogLevel.Full;
}
void Update () {
}
void OnGUI()
{
GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString());
}
public override void OnJoinedLobby ()
{
Debug.Log("join lobby!");
PhotonNetwork.JoinRandomRoom ();
}
void OnPhotonRandomJoinFailed()
{
Debug.Log("Can't join random room!");
PhotonNetwork.CreateRoom(null);
}
void OnJoinedRoom()
{
Debug.Log("join random room!");
GameObject monster = PhotonNetwork.Instantiate("monsterprefab", Vector3.zero, Quaternion.identity, 0);
}
}
PUN has some new components since their new update.
I'd recommend you to use those components because it is really user friendly towards new users.
Some components you could use:
PhotonTransformView
PhotonRigidbodyView
PhotonAnimatorView
These three components will help you sync your position, physics and animations on the GameObject it is attached to.
If you do not want to use these components i suggest you search up: interpolation and extrapolation for Unity PUN.
Some good starting tutorials:
SkyArena PUN Tutorial This is a really good video tutorial[in parts] on PUN so you should definitely check that out.
Exit Games Marco Polo This tutorial is created by someone from PUN also really good to read even if you don't need it.
Hope this will help you.
-Menno
I found the answer in Demo Synchronization that provided in PUN plugin, it is really helpful.

Categories