OnMouseOver works differently on same objects - unity3d

I am a beginner in Unity and I just found out a behaviour I do not understand...
I have a prefab "cell" that I made from a sprite and I want it to change its color when my mouse is over it.
So I added a BoxCollider2D component to it as well as the following script:
public class Cell : MonoBehaviour
{
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
private void OnMouseOver()
{
GetComponent<SpriteRenderer>().color = Color.magenta;
}
private void OnMouseExit()
{
GetComponent<SpriteRenderer>().color = Color.black;
}
}
Then when I drag and drop the "cell" prefab to the scene, it won't work (when my mouse is over the cell, nothing happens).
Same problem when I add another "cell" prefab to the scene.
But when I add a third "cell" prefab to the scene, the feature works on the 2 first cells but not on the third.
I probably missed something or there is a behaviour I do not know, anyway if someone knows why this is happening, please tell me.
Thanks!

I just tested your code in my game using a 2d box sprite and it works fine.
Video > https://youtu.be/6GP3-aV9g3g
You may want to try a couple of things to debug it.
First make sure that there is a BoxCollider2D and Rigidbody2D attached.
Make sure that there is nothing covering the boxes in the scene.
When I am having trouble with an aspect of the game I try to break it down into its simplest components. Try making a scene with nothing in it apart from the box and trying it, if that doesent work, try attaching the scrip to a non prefab object.
Try adding Debug.Log("Mouse Enter"); to the subs to check if the mouse is detected on enter, if it is detecting the mouse, maybe your spite renderer isn't working properly.
Try these things and let me know if they don't work, I would be happy to keep trying to figure it out.

Related

Unity: Drag & Drop script doesn't work on my prefab gameobject but DOES work on regular UI gameobjects

I have a simple script that works just fine on any normal UI objects like an image.
But it doesn't work at all for my prefab gameobject, why is that?
I have attached a whole bunch of components to try out, like images, canvas renderer and all kinds, nothing works for me. I can also only SEE the damn prefab when I run the game, I can't see it on the Game tab. I have no clue. This is so strange.
Anyways, If I didn't make myself clear, please let me know what I need to explain or include for anyone to give me an answer?
public class DragAndDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("onBegindrag");
}
public void OnDrag(PointerEventData eventData)
{
this.transform.position = eventData.position;
Debug.Log("ondrag");
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("onEndDrag");
}
}
Does this script only work on UI things? If so, Can I add a component to my prefab so that it is a UI item? Im working in 2d.
By default these primerily UI events are only casted onto UI elements (Image, Text, etc) which have Raycast Target enabled (using the GraphicsRaycaster component attached to the according Canvas).
If you want to be able to also use them on "normal" 3D objects you need
An EventSystem in your scene (already the case otherwise it wouldn't work for UI either)
Collider components on your objects
A PhysicsRaycaster component on your Camera!
For some reason I don't know this is only mentioned in the IPointerClickHandler (Unity 2019.1 and older) but afaik this still applies to all the EventSystem-related events / interfaces.

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 start Audio at specific moment

I am new to Unity and I have a little menu which comes up with the logo coming into the screen. Now I want to add a mp3/wav which gives an audio while the logo comes into the screen. The audio should stop when the logo appearance also stops.
How can I put the audio at the exact same moment when the logo (png) appears?
Thank you in advance :)
It might be an overkill solution for your simple case but you could try using Unity Timeline
https://docs.unity3d.com/Packages/com.unity.timeline#1.5/manual/index.html
You can setup all the menu animations with sounds and then play it on click.
https://learn.unity.com/tutorial/starting-timeline-through-a-c-script-2019-3#
All you need to do is have a reference to the AudioSource that has the audio you want to play and use the Play and Stop methods. It is also important to assure you have the field PlayOnAwake turned off as that will play the audio the moment the scene starts.
I do not know how you are currently moving your object, so here is a very generic answer as to how you can approach this using the information I gave above.
[SerializeField] private AudioSource yourAudio = null;
private void IEnumerator Movement
{
yourAudio.Start();
while(movement)
{
// your movement code here (assure there is a yield return null)
}
yourAudio.Stop();
}
With some code or more detail, I can tweak the above snippet but the main idea can be applied to however you are doing your movement. If you want to stop the audio the moment the logo appears on screen, that is a different approach, so let me know if that is what you meant.
Just for completeness, if you want to just stop or start this audio whenever your logo is visible or no longer visible, here is an approach. Be warned though, this approach will be triggered by the editor camera as well, so if something unexpected happens close or toggle off your scene view.
public class YourLogoScript : MonoBehaviour
{
[SerializeField] private AudioSource yourAudio = null;
// stop audio when invisible
void OnBecameInvisible()
{
yourAudio.Stop();
}
// start audio when visible
void OnBecameVisible()
{
yourAudio.Start();
}
}
By using OnBecameInvisible and OnBecameVisible, whenever the renderer attached to your logo is seen by any (including scene view) camera, the OnBecameVisible function is called and when it is no longer seen, the OnBecameInvisible is called.

There is no reason for this Unity script to make the sprite move, yet it moves

Here's the code:
using UnityEngine;
public class playerMovement : MonoBehaviour {
public Rigidbody2D rb;
public float strength = 100f;
void Start () {
//Initialize the body of the sprite so that forces
//can be applied.
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void FixedUpdate () {
//Note2Self: var says this is a variable of unspecified type.
var touch = new Touch();
/*
if (touch.phase == TouchPhase.Began){
rb.AddForce(transform.forward * strength);
}*/
if (Input.anyKey)
rb.position.Set(0, 100);
}
}
I was trying to practice some basic stuff in Unity (I am not used to programming in IDE's at all, we've just used vim in my program so far) when I happened upon this oddity.
First, I didn't understand why the sprite would move at all when there can't be a touch identification, since I haven't actually tested this on a mobile device. So I commented it out and for some reason the sprite still moves. That code shouldn't be doing anything, yet it is.
I have checked to see if the sprite is using the up-to-date script - it is - and I have checked if the script is targeting the correct rigid body and that it is a rigidbody2D. It is.
What is going on?
If it is just falling it is probably effected by gravity.
You can turn this off in your script by adding rb.gravityScale = 0; at the end of your Start() function
OR
by setting it in the editor inside the rigid body component
I looked in the unity documentation:
https://docs.unity3d.com/ScriptReference/Rigidbody2D.html
which says that applying a Rigidbody2D component to an object will place it under control of the physics engine.
The Rigidbody2D class essentially provides the same functionality in 2D that the Rigidbody class provides in 3D. Adding a Rigidbody2D component to a sprite puts it under the control of the physics engine. By itself, this means that the sprite will be affected by gravity and can be controlled from scripts using forces.
I have run into issues with rigidbodies on more than one occasion, I suggest you check the RigidBody2D component in the unity inspector window and make sure to uncheck use gravity.
Also, you may want to just write a custom script without using a rigidbody. Doing a search on youtube will probably give you exactly what you need for that. Hope this helps!

Unity | 'gameobject.renderer.material.color' in version 5.x

I want to make a portion of the gameObject(guiTexture or sprite) as transparent color like "SpriteMask" which is in asset store.
https://www.assetstore.unity3d.com/kr/#!/content/27642
Let me explain in more detail.
For example, there are two gameObject in the scene. One is the background of the scene and the other one is just empty gameObject which can move when i drag it.
The portion that gameObject is located of background should be made transparent simultaneously.
First, I tried it to use 'rendere.material.color.a' but it's deprecated in Unity version 5.x. Now I have no idea.
Below is all i want to do.
https://www.drupal.org/files/project-images/Manual-Crop.jpg
Does anyone have good idea? How can i make it in simple way.
Please give any idea. Thank you.
Make a global variable
MeshRenderer renderer;
Start()
{
renderer = gameObject.GetComponent<MeshRenderer>() as MeshRenderer;
}
now you can use renderer!
Update for 5.3.0f4 :
public GameObject mainObj;
void Start () {
mainObj.GetComponent<MeshRenderer> ().material.color.a = 1.0f;
}
unity3d c#