Unity3d 3d skybox not quite right - unity3d

I'm messing around in unity3d in order to learn it.
Had a crack at making my own 3d skybox like in source engine for example. I'm using the standard 1st person controller.
I made another camera with same FOV for my skybox, and slaved it to the camera in the 1st person controller using the script below which I put on my skybox camera.
(Maincam field has the 1st person controller camera component in it)
using UnityEngine;
using System.Collections;
public class CameraSlave : MonoBehaviour {
public Component Maincam;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.rotation = Maincam.transform.rotation;
}
}
You can see result here. Its a bit funny. (The big tetrahedron shape in the background is in my skybox everything else is normal)
As far as I understand it as long as the camera fov is the same it doesnt matter what size my skybox things are.
I think the problem, is there is some lag maybe? Like the Update in the code above is being called one frame too late? I tried calling that update from the 1st person controllers mouse look script but as well as getting loads of errors the result was the same.

I can't visualize your example, btw:
I think the problem, is there is some lag maybe? Like the Update in
the code above is being called one frame too late? I tried calling
that update from the 1st person controllers mouse look script but as
well as getting loads of errors the result was the same.
You can't rely on the order in which Update method will be called by the engine (unless you force a particular order, but this isn't generally a good choice). For camera update operations it's better to use LateUpdate. It's guaranteed that it will be called after all Update methods.

Related

How to animate grabbing in Unity VR?

I've been googling this for 10 hours and I'm running out of ideas. I found several video-tutorials and written-tutorials but none of them really works or they're overkill.
I have VR Unity (2020.3.16f) project designed to be run on Quest 2. I'm not using OpenXR. I already created hand, created one simple grabbing animation, added animation to Animator, created transitions, and set "IsGrabbed" parameter. Now I'm looking a simple way to change "IsGrabbed" to true/false whenever I grab/release anything. I'm expecting something like this:
public class grabber : MonoBehaviour
{
// Start is called before the first frame update
Animator animator;
???
void Start()
{
???
}
// Update is called once per frame
void Update()
{
if (???)
{
animator.SetBool("IsGrabbing", true);
}
elseif (???)
{
animator.SetBool("IsGrabbing", false);
}
}
}
Please help. We're talking about VR here so I'm sure grabbing animation is the very basics of very basics of very basics. It can't be any difficult.
Best regards
First of all, I highly recommend watching this video by Justin P Barnett to get a much better overview of how this all works.
If you don't want to go that route for some reason, there are other options available to you. One such option is the "Player Input" component, which can act as a bridge between your input devices and your code. Most XR packages these days use the new Input System package, and it makes life easier, so I will assume you have that installed.
First, you will need to create an Input Actions asset, which can be done in the project pane: right-click -> Create -> Input Actions. There are many tutorials which explain this asset in detail, but here is a simple setup to get you started. Double click on the new asset to open the editing window, and create a new Action Map. In the "Actions" list, create a new action with action type Value, Control Type Axis, and in the dropdown arrow on your new action set the path to the input source. As an example source path, I will use XR Controller -> XR Controller -> XR Controller (Left Hand) -> Optional Controls -> grip. Make sure to click Save Asset before closing the window.
Create a script similar to this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class ControllerInputReceiver : MonoBehaviour {
public void FloatToScale(InputAction.CallbackContext context) {
float val = 0.1f + 0.1f * context.ReadValue<float>();
transform.localScale = new Vector3(val, val, val);
}
}
Create a cube somewhere visible in your scene, and add the Input Action Manager component to it, and drag your created Input Actions asset to its list of Action Assets. Then add the ControllerInputReceiver script. Also on this cube, create a Player Input component and drag your Input Actions asset to its Actions element. Choose your map as the default map and change behavior to Invoke Unity Events. Under the events drop down, you should see an element for the Action you created earlier. Drop your Controller Input Receiver component into this Action and select the FloatToScale function.
In theory it should work at this point. Build the game to your device and see if pulling the grip causes the cube to resize. If it does, then you can replace your Update function with:
void SetGrabbing(InputAction.CallbackContext context) {
animator.SetBool("IsGrabbing", context.ReadValue<float>() > cutoff);
}
If you are still having issues at this point, I really recommend checking out these youtube channels. I only started VR a couple of months ago and learned everything I know so far from these people. JustinPBarnett, VRwithAndrew, ValemVR, LevelUp2020. (Links removed because it kept screwing up my post)
Note, the new input system has button options instead of value/axis options for VR devices. These may be closer to what you want, but I had no luck getting them to work today.
Also note, depending on how you organize your code, you may or may not need the "Input Action Manager" component somewhere in your scene with your input actions asset in its list. It enables your actions for you, without you needing to do this programmatically.
Another solution would be:
Using the OVR plugin and Hands prefab (for left and right), to check whether the rotation of each of the fingers on a specific axis (ex. Z-Axis) falls under a specific range-meaning fingers are grasping/flexed.
By referencing for example the Transform of b_l_index1 , which is the corresponding part of the Index Finger within the model, you can check its local roation every frame and trigger the event of grasping when all fingers are rotated to a specific angle. Subsequently, triggering the animation you need.

How to make transparent UI visible in Unity Editor?

BackGround
In Unity 2020LTS, I want to make a UI scene.
But in Game Panel, I discovered, although a animation is set at beginning (no conditions), the game will show what I see in Editor panel for a little time at first, then play the animation.
The StateMachine is Entry -> Target(Default)
I don't want show player what I see in editor, but only the first frame in animation.
I guess this is because loading level costs some time (almost 0.5 secs).
Question
So I try another way, make initial state of all objects be same as the first frame of animation.
This way work, seems just like it freeze at first frame for 0.5secs. However, I can't edit those objects visibly (Because they all are transparent in first frame).
I have tried Gizmos, but they don't work well. Besides, Gizmos makes me have to create lots of classes in C# scripts for each object, which just is component of animation and has no script.
Could there be any better way to show transparent (UI) object in editor scene only ?
Assuming you have some Game Manager script, you can add a GameObject, assigning it the UI element, and in the Start() function of the script, make it inactive, like so:
public class GameManager : MonoBehaviour
{
public GameObject menu;
void Start()
{
menu.SetActive(false);
//other statements
}
}
I'm not quite sure what you asked for but if you want to edit the UI elements that are invisible you can simply select them by using the hierarchy and edit them. I have linked an image with an example of this. Example scene with invisible panel
Image img;
// Start is called before the first frame update
void Start()
{
img = GetComponent<Image>();
img.color = new Color32(0, 0, 0, 0);
}
The code above will set the panels transparency to zero when the scene starts, make sure to use the using unity.UI namespace in order to acess the image component.

Unity | How to play animations that are stored in a variable (without having them in the animator)

I'm creating a 2D fighting game, where the player can choose from a number of fighters. the fighters have different attacks with different animations.
the data (damage, hitbox, cast time, animation, etc.) for every attack is stored in a Scriptable Object that is then triggered by the player script. this worked out fine so far, but I can't find out how to play an animation from code without needing it to be in the animator.
I've tried several solutions that I found here but they seem to end up having to fall back to putting the animation in the animator.
but I can't find out how to play an animation from code without needing it to be in the animator.
You will need the Animator-Component to run an animation.
But you can assign the animation you want to play at runtime. For this you need the RuntimeAnimationController to hold the AnimatorController-object and assign it to your Animator (in code).
You do not necessarily need the Animator component as stated in this answer.
There is also the Animation component. It is marked as legacy but is still quite powerful especially when you do not need to configure an entire state machine but want to rather simply playback single AnimationClip. Might be the reason why this still makes it into newer Unity versions:
public AnimationClip clip;
private void Awake()
{
var animation = GetComponent<Animation>();
animation.clip = clip;
animation.Play();
}
Also see Animation.Play

Two Cameras need them to face each other

I have two cameras in a scene,both following different objects I want to make them face each other ,like split screen but opposite sides,also I don't want to touch the rotation of the camera,any heads up with playing with cameras and split screening would be a great help,thanks!
This may be the thing you are looking for
// This complete script can be attached to a camera to make it
// continuously point at another object.
// The target variable shows up as a property in the inspector.
// Drag another object onto it to make the camera look at it.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public Transform target;
void Update() {
// Rotate the camera every frame so it keeps looking at the target
transform.LookAt(target);
}
}
http://docs.unity3d.com/ScriptReference/Transform.LookAt.html
Found an easy way,created an empty gameObject rotated it upside down and inserted the second camera in it,still any other solutions are welcome and tips for multiplayer on same phone would also be great help,thanks!
Edit:This does not work.

How to change cameras in Unity based on camera coordinates?

I'd like to create a movie in Unity, so I would need several cameras and camerapaths.
On the top of this off course I'd like to change between them. For example if Camerapath1 reaches a significant point with Camera1 then I'd like to change to Camerapath2 with Camera2, etc.
I also have Camera Path Animator asset installed. It's working perfectly when I'm using it with only one camera for several camerapaths but I'm unable to change between maincameras.
I'm a newcomer to Unity. I also know that I should do something like this:
...
camera1.camera.active = false;
camera2.camera.active = true;
...
...but where should I populate these lines? On the top of this, how may I catch the event when a camera on a specific camerapath reaches a particular point?
The way to go would be an animation controller that has all camera as children and controls the active state of all cameras. This provides perfect control over the behaviour.
Create an empty game object, add all cameras as children, add an Animator to the main object with one animation. This animation takes all the camera and set their active state. One extra bonus of this approach is the possibility to call methods as well using the AnimationEvent process. You can still define within the animation for some triggered actions like explosions or movements of objects.
As I said, this give you perfect control since you can define easily actions at specific time.
The downside of it is the rigidity of the process. It may not be as flexible as code, but since you are making a movie, you probably do not need flexibility.
If so, you would have your cameras with a collider and rigidbody (isKinematic true), then you would have some trigger box with a simple script:
public void CameraTrigger:MonoBehaviour{
public GameObject nextCamera;
void OnTriggerEnter(Collider col){
if(col.gameObject.CompareTag("Camera")){
col.gameObject.SetActive(false);
nextCamera.SetActive(true);
}
}
}
Then you drag the camera meant to start next as nextCamera.