Im using Inventory system by Brackeys here, then i try to custom an equipment object just like the documentation says. I need that item enable Renderer Sprites component when object drag to weapon holder (inventory), and disable Renderer Sprites when object drag out from weapon holder. I'm implementation GetComponent(SpriteRenderer).enabled = true; for activating Renderer Sprites and GetComponent(SpriteRenderer).enabled = false; to disable, but the script seems don't work, when the object drag out from inventory, Renderer Sprites Component still active. here the part of script for enable/disable Renderer Sprites
#pragma strict
//This script allows you to create equipment effects that will be called either OnEquip or WhileEquipped. This is usefull for magic effects and stat handling.
#script AddComponentMenu ("Inventory/Items/Equipment Effect")
#script RequireComponent(Item)
private var effectActive = false;
function Update ()
{
if (effectActive == true)
{
//-----> THIS IS WHERE YOU INSERT CODE YOU WANT TO EXECUTE AS LONG AS THE ITEM IS EQUIPPED. <-----
}
}
function EquipmentEffectToggle (effectIs : boolean)
{
if (effectIs == true)
{
effectActive = true;
Debug.LogWarning("Remember to insert code for the EquipmentEffect script you have attached to " + transform.name + ".");
//-----> THIS IS WHERE YOU INSERT CODE YOU WANT TO EXECUTE JUST WHEN THE ITEM IS EQUIPPED. <-----
GetComponent(SpriteRenderer).enabled = true;
}
else
{
effectActive = false;
//-----> THIS IS WHERE YOU INSERT CODE YOU WANT TO EXECUTE JUST WHEN THE ITEM IS UNEQUIPPED. <-----
GetComponent(SpriteRenderer).enabled = false;
//Destroy(gameObject);
}
}
is it correct implementation ? what should i do ?
you should read up on collisions and triggers....have them toggle the renderer enabled or disabled in the script.or better yet have the inventories do that....i don't think it's very efficient they way you're trying.
i.e. set the inventories as Triggers and have OnTriggerEnter(collider col) do col.gameObject.GetComponent().enabled = true;
and OnTriggerExit(collider col) do col.gameObject.GetComponent().enabled = false;
if you're using Unity's 2D components then it's OnTriggerEnter2D(Collider2D col) and so on.....
this is just an example and far from 100% fullproof code.just a nudge towards a possible way.you probably need to set some more things.
Related
Basically on my map I'm trying to use Physics.CheckBox detect when the player is in certain areas to determine where my enemies will spawn at. I am using a layer mask to detect when its colliding with the player and Gizmos to visualize this box in the editor. The issue I'm having is that it will return true even when the player isn't inside the box. I have verified every single other game item does not have the player layer mask causing it to return true when it hits something else. The kicker is Physics.CheckSphere works perfectly except for the fact that my map is square, not circle, so I can't use check sphere because I can't cover all of the areas I need to cover.
Code for both is as follows, note that both of these lines are not in my script at the same time I alternated them out for testing:
atNeighborhood = Physics.CheckSphere(spawnAreas[0].transform.position, neighborhoodRange, playerLayer);
atNeighborhood = Physics.CheckBox(spawnAreas[0].transform.position, neighborhoodRange, Quaternion.identity, playerLayer);
Why would the CheckBox return true when colliding with items not in the layer mask but the CheckSpere works perfectly and only returns true when colliding with the player? Anyone have any idea?
LET ME KNOW IF THERE ARE ANY PROBLEMS OR ERRORS IN COMMENTS. THANKS!
Ok. CheckBox can get kind of confusing sometimes. I would reccomend something else.
You could use Empty Game Objects with colliders on them and put them where ever you want. IsTrigger must be set to true. Imagine these as "zones", where whenever you step in one, something can happen.
All you have to do is set a certain tag to each zone to activate different things.
Note: Player does not need rigidbody, but it would be a whole lot less messy if you did.
Here is a script if your player does have a rigidbody (put this script on your player):
void OnTriggerEnter(Collider obj)
{
if (obj.gameObject.CompareTag("Zone 1"))
{
SpawnZombies();
}
}
Player doesn't have rigidbody:
If your player does not have a rigidbody, you could put a bunch a script on each one called "zone activator".
Important Notes for this version:
Your player must have a collider and a unique tag.
On each zone add a rigidbody.
Make sure detectCollisions is false!
Make sure useGravity is false!
This zone detector should have it's collider be a trigger;
(You do not want this thing to move!)
You can now create a script that goes on each zone:
public string message;
public bool inZone;
void OnTriggerEnter(Collider obj)
{
if (obj.gameObject.CompareTag("player"))
//Or set it to whatever tag the player has
{
inZone = true;
}
}
void OnTriggerExit(Collider obj)
{
if (obj.gameObject.CompareTag("player"))
//Or set it to whatever tag the player has
{
inZone = false;
}
}
You must then reference this in the player's script
public ZoneDetector[] allZones;
void Update()
{
//.....
foreach (ZoneDetector zone in allZones)
{
if (zone.inZone == true)
{
if (zone.message == "zone 1")
{
DoZone1();
}
if (zone.message == "zone 2")
{
DoZone2();
}
}
}
}
I Have a player which gets childed to a game object when it walks up to a trigger now I want the player's parent to become null again after space is pressed because I'm trying to make a rope system, and it's required for the player to be able to de-attach from the rope
This is the script that's supposed to attach/detach the player from the rope
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AttachToRope : MonoBehaviour
{
public GameObject objectToParentTo;
public GameObject objectWithSwingScript;
// Start is called before the first frame update
private void OnTriggerEnter(Collider collider)
{
if (collider.gameObject.tag == "Rope")
{
transform.parent = objectToParentTo.transform;
objectWithSwingScript.GetComponent<playerscript>().enabled = true;
GetComponent<PlayerController>().enabled = false;
GetComponent<CharacterController>().enabled = false;
GetComponent<Swinging>().enabled = false;
}
}
private void OnTriggerStay(Collider collider)
{
if (Input.GetButtonDown("Jump"))
{
transform.parent = null;
objectWithSwingScript.GetComponent<playerscript>().enabled = false;
GetComponent<PlayerController>().enabled = true;
GetComponent<CharacterController>().enabled = true;
GetComponent<Swinging>().enabled = true;
Debug.Log("Deattached");
}
}
}
What happens when the player enters the trigger is that the scripts that make the player move get disabled and then it gets chilled to the last section of the rope now in ontriggerstay i want it to check if space is pressed and re-enable all the scripts that are required for the player to move (which does not work) but since nothing in there works i tried to debug.log but even that does not work so if anyone knows how to fix this please help me
From the OnTriggerStay documentation: The function is on the physics timer so it won't necessarily run every frame.
Functions on the physics timer (e.g. FixedUpdate()) don't play nicely with Input.GetButtonDown because they don't run every frame. Instead, they run on a fixed timestep, 0.02 seconds by default.
The solution is to put calls to Input.GetButtonDown into Update(). For instance, in this example you could have a boolean member variable isJumpPushed and set it to true in Update() when the jump button is pushed and the player is attached, and then check that value in OnTriggerStay.
--
A note about debugging:
I tried to debug.log but even that does not work
If your Debug.Log isn't showing a log in the console, that still tells you something important. It tells you that code path isn't getting called. That's an important clue for you to figure out what's really going on. To further narrow down the problem, you could move the Debug.Log statement outside the if statement. This would show that it's Input.GetButtonDown that isn't returning true when you think it is.
Hello I'm developing a Vuforia AR image recognition app.
However, I wish to make an object appear upon scanning an image, and that image to stay unattached(not affected by the location of scanned image and has a fixed coordinate in the camera) to the image being recognized.
How can I make this happen ?
is this done through a script? if so, how can i script it ? and where will I add the script component ?
what I tried so far is
just followed this video
but used a different target and object
and I just want to make the object that appears after recognition be unattached
thank you in advance.
I don't know if you still following this post.
Here is your answer :
How can I make this happen ?
By transferring the 3D model to the camera.
is this done through a script?
Yes.
if so, how can i script it ?
First you need to know what kind of "Stick" you want. Is there a trigger button or it just stick when the camera moved away from the marker?
If there's a trigger button, you can script it such when you click/tap at the button, it change the 3D's (GameObject) parent to the camera.
my3D.transform.SetParent(Camera.main.transform);
If you want to make it such that when you move your camera away, and
the 3D model automatically stick to camera, it will slightly more
complicated. You need to access to the
ImageTargetTrackableEventHandler.cs in the VuforiaImageTarget object.
Look for a function called OnTrackingLost(). Instead of :
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
// Disable rendering:
foreach (Renderer component in rendererComponents)
{
component.enabled = false;
}
// Disable colliders:
foreach (Collider component in colliderComponents)
{
component.enabled = false;
}
you remove the whole chunk of code by disable it, and on top of the
scripts add in
[SerializeField]
GameObject my3D;
and inside the OnTrackingLost() function, put in this code :
my3D.transform.SetParent(Camera.main.transform);
After that, go to the Inspector view, click on the ImageTarget, there
will be something like this :
simply drag your 3D from the Hierarchy view to the variable image
shown.
and where will I add the script component ?
if you're using the "button" method, simply create an empty gameobject
and attach the script to it.
Hope it helps, because there is very limited support out there for vuforia. :)
the only thing that worked for me was adding a boolean variable at the begining of the script, and make it that when OnTrackingLost() enters, the boolean becomes true. I don't know if I explain myself.
First you create at the begining:
private bool bol = false;
Then on the function:
private void OnTrackingLost()
{
Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
if (!bol) {
// Disable rendering:
foreach (Renderer component in rendererComponents)
{
component.enabled = false;
}
// Disable colliders:
foreach (Collider component in colliderComponents)
{
component.enabled = false;
}
bol = true;
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
}
In Unity I want to change scenes when the player enters a certain area. The area has box collider and it is set as a trigger, and the script is attached to that area, however when the player enters that area and presses up on their keyboard, nothing happens. I have no syntax errors and it says everything is fine. What could the issue be?
Here is the code:
var Level = "";
var Player = "";
function OnTriggerStay(other : Collider) {
if(other.tag == Player){
if(Input.GetKeyUp("up")){
Application.LoadLevel(Level);
}
}
}
Revised code:
var Level = "";
var Player = "";
function OnTriggerStay (consolelog("Hello"))l;
{
if(other.tag == Player){
if(Input.GetKeyDown("up")){
Application.LoadLevel(Level);
}
}
}
So your code is Ok. I setup new project.And your code works fine.
Possible pitfalls:
1. You misspell either player tag either level name
2. You did not add level in build settings
3. One of colliders has to have rigidbody - docs
P.S. Problem was with a setup: mix colliders 2d and 3d.
I have a simple touch/mouseclick script attached to a GameObject as a sort of "Master Script" i.e. the GameObject is invisible and doesn't do anything but hold this Touch script when the game is running.
How do I tell other named GameObjects that are generated at runtime to do things e.g. highlight when touched/clicked from this Master Script?
The script for highlighting seems to be: renderer.material.color= colorRed;
But I'm not sure how to tell the GameObject clicked on to become highlighted from the Master Script.
Please help! (am programming in C#)
Thanks!
Alright so you'll want to use a ray cast if you're not doing it in GUI. Check out Unity Ray Casting and then use
hit.transform.gameObject.renderer.material.color = red;
You can have a switch that is like:
if (hit.transform.gameObject.CompareTag("tag")) {
// turn to red;
} else {
// turn to white;
}
Use the ScreenPointToRay or ScreenPointToWorld depending on what you're doing.
For touch, should look like:
void Update () {
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay(touch.position);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000.0f))
{
if (hit.collider.gameObject.CompareTag("tag"))
{
hit.collider.gameObject.renderer.material.color = red;
}
}
}
// You can also add in a "go back" feature in the update but this will "go back" then when the touch ends or moves off
// Also not so good to search for Objects in the update function but that's at your discretion.
GameObject[] gObjs = GameObject.FindGameObjectsWithTag("tag");
foreach (GameObject go in gObjs) {
go.renderer.material.color = white;
}
}
To answer your question about pinging the 'manager'
I would do one of two options.
Either:
// Drop the object containing YourManager into the box in the inspector where it says "manage"
public YourManager manage;
// In the update and in the Ray Cast function (right next to your color change line):
manager.yourCall ();
// and
manager.yourString = "cool";
OR
private YourManager manage;
void Awake () {
manager = GameObject.FindObjectWithTag("manager").GetComponent<YourManager> ();
}
// In the update and in the Ray Cast function (right next to your color change line):
// In your manager file have "public bool selected;" at the top so you can access that bool from this file like:
manager.selected = true;
I detail this a little in another one of my answers HERE
For mouse clicks, I would check out the MonoDevelop functions they have in store such as:
// This file would be on the game object in the scene
// When the mouse is hovering the GameObject
void OnMouseEnter () {
selected = true;
renderer.material.color = red;
}
// When the mouse moved out
void OnMouseExit () {
selected = false;
renderer.material.color = white;
}
// Or you can use the same system as above with the:
Input.GetMouseButtonDown(0))
Resolution:
Use a bool in your manager file true is selected, false isn't. Have all the objects you instantiate have a tag, use the ray cast from the master file to the game object. When it his the game object with that tag, swap colors and sap the bool from the master file. Probably better to do it internally from the master file.
(All depends on what you're doing)
If you know what the name of the GameObjects will be at runtime, you can use GameObject.Find("") and store that in a GameObject variable. You can then set the renderer of that GameObject to whatever you like (assuming a renderer is linked to that GameObject).
The most obvious way of doing this would be to use prefabs and layers or tags.
You can add a tag to your prefab (say "Selectable") or move the prefab to some "Selectable" layer and then write your code around this, knowing that all selectable items are on this layer/have this tag.
Another way of doing this (And in my opinion is also a better way) is implementing your custom 'Selectable' component. You would search for this component on a clicked item and then perform the selection, if you have found that component. This way is better because you can add some additional selection logic in this component which would otherwise reside in your selection master script (image the size of your script after you've added a couple of selectables).
You can do it by implementing a SelectableItem script (name is arbitrary) and a couple of it's derivatives:
public class SelectableItem : MonoBehavior {
public virtual void OnSelected() {
renderer.material.color = red;
}
}
public class SpecificSelectable : SelectableItem {
public override void OnSelected() {
//You can do whatever you want in here
renderer.material.color = green;
}
}
//Adding new selectables is easy and doesn't require adding more code to your master script.
public class AnotherSpecificSelectable : SelectableItem {
public override void OnSelected() {
renderer.material.color = yellow;
}
}
And in your master script:
// Somewhere in your master selection script
// These values are arbitrary and this whole mask thing is optional, but would improve your performance when you click around a lot.
var selectablesLayer = 8;
var selectablesMask = 1 << selectablesLayer;
//Use layers and layer masks to only raycast agains selectable objects.
//And avoid unnecessary GetComponent() calls.
if (Physics.Raycast(ray, out hit, 1000.0f, selectablesMask))
{
var selectable = hit.collider.gameObject.GetComponent<SelectableItem>();
if (selectable) {
// This one would turn item red or green or yellow depending on which type of SelectableItem this is (which is controlled by which component this GameObject has)
// This is called polymorphic dispatch and is one of the reasons we love Object Oriented design so much.
selectable.OnSelected();
}
}
So say you have a couple of different selectables and you want them to do different things upon selection. This is the way you would do this. Some of your selectables would have one of the selection components and others would have another one. The logic that performs the selection resides in the Master script while the actions that have to be performed are in those specific scripts that are attached to game objects.
You can go further and add OnUnselect() action in those Selectables:
public class SelectableItem : MonoBehaviour {
public virtual void OnSelected() {
renderer.material.color = red;
}
public virtual void OnUnselected() {
renderer.material.color = white;
}
}
and then even do something like this:
//In your master script:
private SelectableItem currentSelection;
var selectable = hit.collider.gameObject.GetComponent<SelectableItem>();
if (selectable) {
if (currentSelection) currentSelection.OnUnselected();
selectable.OnSelected();
CurrentSelection = selectable;
}
And we've just added deselection logic.
DISCLAIMER: These are just a bunch of snippets. If you just copy and paste those they probably wouldn't work right away.