Hey guys I'm having a small issue with ARKit and Unity.
In the game that I'm making I'm reloading my scene when the player dies, however when the scene is reloaded all the GameObjects are still in the same position from the last session. I want all my objects to return to their starting positions when the scene is reloaded.
I saw that some variables regarding position and rotation are marked as "static" in the code. I tried changing them but I got a lot of compile errors.
Does anyone know a way around this?
Create this method and call it whenever you want to reset the scene:
using UnityEngine.XR.iOS;
.
.
.
public void ResetScene() {
ARKitWorldTrackingSessionConfiguration sessionConfig = new ARKitWorldTrackingSessionConfiguration ( UnityARAlignment.UnityARAlignmentGravity, UnityARPlaneDetection.Horizontal);
UnityARSessionNativeInterface.GetARSessionNativeInterface().RunWithConfigAndOptions(sessionConfig, UnityARSessionRunOption.ARSessionRunOptionRemoveExistingAnchors | UnityARSessionRunOption.ARSessionRunOptionResetTracking);
}
I found the solution!
Add these lines of code in your ARCameraManager script in the "!UnityEditor" part.
UnityARSessionRunOption options = new UnityARSessionRunOption();
options = UnityARSessionRunOption.ARSessionRunOptionRemoveExistingAnchors | UnityARSessionRunOption.ARSessionRunOptionResetTracking;
m_session.RunWithConfigAndOptions(config, options);
Now every time you reload your scene all AR elements (planes, anchors, camera tracking data) are reset.
Related
I am trying to load an animation from an fbx file and have it play on a GameObject:
TestObject.AddComponent<Animation>();
animation_handler = TestObject.GetComponent<Animation>();
walking_anim = Resources.Load("fbx_anims/walking_anim_test", typeof(AnimationClip)) as AnimationClip;
if(walking_anim == null)
{
Debug.Log("walking anim not found");
}
walking_anim.legacy = true;
animation_handler.AddClip(walking_anim, "walking");
animation_handler.wrapMode = WrapMode.Loop;
In the game loop, I tried using this:
if (Input.GetKeyDown(KeyCode.W))
{
if (!(animation_handler.IsPlaying("walking")))
{
animation_handler.clip = walking_anim;
animation_handler.Play("walking");
}
}
It doesnt give any errors, yet it doesn't work either. Anything I'm missing?
EDIT: For clarification: The model stays in the default T-Pose, after pressing 'W'. After inserting Debug.Logs at different points, I can confirm that the Play function is getting called only once, after which IsPlaying always returns true. Yet the "playing" animation causes no visual changes in the model (yes, the bone names are the same).
You don't want to use the Animation component, it is an old legacy component that has been replaced by the much improved Animator component. There are a lot of good posts on the Internet on how to use it - no need to repeat it here. The important steps are:
Add the Animator (not Animation) component to the model.
Create an "Animator Controller" in your project and add the clips (like the "walking_anim"). Here you can have a lot of different clips and tell Unity how to interpolate between them by using different parameters.
Add the "Animator Controller" to your "Animator" component.
Add an "avatar" of your model (usually created when the model is imported).
By code alter the parameters of the Animator Controller to tell it which animation clips to play.
It may look like a lot of steps, but it is not so hard and you will quickly have a walking, running, jumping creature on your screen. Good luck!
Overview
I wanted to have a cube, that I can drag around the scene with the components Collider, Rigidbody and ObjectManipulator. In play mode everything works fine, but running it on the hololens, the cube starts flying around after dragging it a few time.
Steps to reproduce (All components are set via editor, not via code)
Create new project and set it up for AR/HoloLens
Import MRTK 2.4
Create cube with a Box Collider. Set Is Trigger = true
Add Rigidbody to cube. Set Use Gravity = false and Is Kinematic = true
Add Object Manipulator to cube. I have a method getting called after On Manipulation Ended, but don't know if thats important.
Expected behavior
The rigidbody is set to Is Kinematic = true and Use Gravity = false, so that the cube stays still/stops moving after releasing dragging it. This works while trying it inside the unity play mode. But running it on the hololens, the cube behaves like Is Kinematic = false and starts flying around after interacting with it. Sometimes after the second drag and sometimes after the third time drag.
Error
Before updating this post, I didnt noticed the development console in left corner of my hololens. At the beginng of the scene I get the message [Physics.PhysX] BV4 midphase only supported on intel platforms but at that moment everything is fine. As the cube begins to fly around I get the a NullReferenceExeption: Object reference not set to an instance of an object.
I fixed my issue. I know the approximate cause, but I do not fully understand it. The method, getting called after OnManipulationEnded caused that.
I have a list, getting filled and drained by OnTriggerEnter/-Exit (exit looks the same, except add→remove):
private void OnTriggerEnter(Collider other){
if (other.gameObject.layer != 31) return;
_objectsCollidingWith.Add(other.gameObject);}
OnManipulationEnded triggered this method:
private int GetMeshes(List<KeyValuePair<Transform, Mesh>> transMeshes){
foreach (GameObject go in _objectsCollidingWith)
{
transMeshes.Add(new KeyValuePair<Transform, Mesh>(go.transform , go.GetComponent<MeshFilter>().mesh));
}
return transMeshes.Count;}
So I got alot of nullreferences from GetMeshes, because some gameobject in the list _objectsCollidingWith were null. Thats because the mesh is getting updated every once in a while. That caused a lot of nullreferences until the cube just flew away.
I used the whole time the logging provider via the device portal and couldnt see what is causing this errors. But after running the project via holographic emulation I could see in the console where they were coming from.
How did I fixed my problem?
I found this post because I realized that my OnTriggerExit didn't get called and cased having null objects and some spatial meshes with the same name triggered OnTriggerEnter very often. Also I added this line in the foreach loop in GetMeshes because once in a while there is still a null object:
if (go == null)
continue;
PS: Please forgive the strange code formatting, somehow the editor here on so does not allow me to place the brackets somewhere else
I am using the A* graph package that I found here.
https://arongranberg.com/astar/download
it all works well in scene view and I was able to set the graph to treat walls like obstacles.
However once I start the game the canvas scales and the graph's nodes no longer align with the walls.
this is really messing up my path finding. If anyone has any ideas how to fix this that would be much appreciated. I tried parenting the graph to the canvas but it still doesn't scale.
Kind regards
For anyone struggling with this what we did is edited the script of the A* code, in the update function we just got it to rescan once. This means that once the game started and all the scaling had taken place the graph re adjusted its bounds. This is probably not the most proper way but it only took four lines and worked for us.
private bool scanAgain = true;
private void Update () {
// This class uses the [ExecuteInEditMode] attribute
// So Update is called even when not playing
// Don't do anything when not in play mode
if (!Application.isPlaying) return;
navmeshUpdates.Update();
// Execute blocking actions such as graph updates
// when not scanning
if (!isScanning) {
PerformBlockingActions();
}
// Calculates paths when not using multithreading
pathProcessor.TickNonMultithreaded();
// Return calculated paths
pathReturnQueue.ReturnPaths(true);
if (scanAgain)
{
Scan();
scanAgain = false;
}
I have created a code file in Unity and assigned it to an empty GameObject I have placed in the scene:
var obj = new GameObject("Sample");
obj.transform.position = new Vector3(0, 0, 0);
var text = obj.AddComponent<TextMesh>();
text.text = "Hello world";
When I run the scene, I can see the text. And that is my problem: I did not specify anywhere in code to add obj to the scene, but it gets placed automatically apparently.
This can be a problem if I want to introduce an object later than instantiation time.
What am I doing wrong? How can this be achieved? What are the patterns/best-practices here?
Immediate fix:
Use obj.SetActive(false) to temporarily disable the object and then use obj.SetActive(true) when you need the object to be active.
Other solutions / best practices:
Create the object you desire in the scene, save it as a prefab (prefabricated object) and then only instantiate it when you need it. Here's a link for further reading into the prefab system. https://docs.unity3d.com/Manual/Prefabs.html
Object pooling is typically used when you will have a bunch of the same objects (like lasers, bullets, etc). Watching this video may be of help: https://www.youtube.com/watch?v=tdSmKaJvCoA
I have created a project and put a character in it, a Ninja. I drew every part of his body and put them together into one organized gameObject. It is organized as this.
Ninja Organization
NOTE : The Left_Arm GameObject has a parent so it can be rotated by the shoulder like a real arm
Now here comes the problem. I've searched and searched for hours and haven't found a solution to something that is surely so simple and dumb. In a script, I try to move the Left_Arm parent for a little animation. Here's the script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NinjaShooting : MonoBehaviour {
[Header("GameObjects")]
public Transform leftArm;
public Transform rightArm;
[Header("Other")]
public bool shooting = false;
// Update is called once per frame
void Update () {
Debug.Log(leftArm.localPosition);
leftArm.localPosition = new Vector3(100, 100, 100);
Debug.Log(leftArm.localPosition);
shooting = false;
}
}
The public variables are all assigned and everything, there are no errors in the console, but the line leftArm.localPosition = new Vector3(100, 100, 100); doesn't seem to do a thing to my character.
Here's is the Console after running it : Image
The console seems alright. The start position is (-0.3, 0.2, 0) and after leftArm.localPosition = new Vector3(100, 100, 100); the position is debugged as (100, 100, 100) as it should be. But the position changes in the inspector, nor in the game window...
Additionnally, the starter position is debugged every frame, but it shouldn't. So I assume that my position isn't taken into account or something.
I've done this so many times, and always has worked.
I even tried with a new project and recreated it, and there, mysteriously, it worked. So there is someting wrong with my organization or something. Sorry if this is a stupid question.
Thank you in advance
PS : Here is an image of the script in the editor, just in case there something wrong with that : Image
PS : The script is a it weird because I simplified it :). But this doesn't work too
This issue is likely caused by an Animator controller "locking" properties that are not actually part of its Motion. In this case, it is "locking" the Transform's position. Unity does not report any warnings or errors when you try to modify those properties, even if they are being controlled by an animation.
The typical offender is the Write Defaults property being set to true for your Animation States in your animation controller. Have a look here at the documentation for what Write Defaults does, and it will make more sense to you. I suggest changing it to false for all animation states that do not need it.