Unity - passing variables from different scripts + making enemies flee - unity3d

Ive seen a few questions similar to mine but I can't get it working for my particular need.
I have 2 scripts both in unityscript, EnemyHealth.js and BasicAI.js . In EnemyHealth.js I have an int variable called Health. I want to pass this over as a variable within BasicAI.js so that I can check whether the enemies health is below a certain range. Both scripts are attached to a game object 'Enemy'.
The second part of my question is, if var Health is below a certain amount (say, 20) I want a function flee() to be called. How would I make the enemy turn away from the player and proceed to move away ?
Thanks.

To answer the first part of your question, you'd want to use (GetComponent)[http://docs.unity3d.com/ScriptReference/GameObject.GetComponent.html]. What this does is lets you get other scripts on a GameObject of a particular type. In your case, you'd be doing something like:
var enemyHealth = gameObject.GetComponent(EnemyHealth);
Then you'd just need a public way to access the variable called Health, whether that variable is public or there is some sort of getter that is public (if you don't want BasicAI altering health, then you'd want to go the getter route instead of just making the variable public).
Now, as to make the enemy flee, that's a pretty complicated question that involves a number of things and I think it might be a bit too broad to answer in general. Might want to look up some basic AI scripting to get a handle on those concepts.

There is various ways to call another script in Unity. Either GetComponent as Brett said but I would use FindObjectsOfType (http://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html) in your case.
The AI question is pretty unclear. Do you already have a AI that does something? Just to call the flee method just type what you said in your question (probably in Update(http://docs.unity3d.com/ScriptReference/MonoBehaviour.Update.html).
if(Health < 20){
flee();
}

Related

Duplicating ScritableObjects with Values per Script Unity

I am making a Multiplayer Game with MLAPI. The problem is, i have a ability system so every ability get executed over an ScritableObject. The problem is, if i have for example five Players in the scene all Players are referenced to the same ScritableObject. And so when somebody execute a ability. The other players are also doing it.
So my Question is can I duplicate my default ability ScritableObject so that every player has its own abilities ScritableObject but with the same Values as the default ability ScritableObject. I must do that over Script.
I know i could create a new ScritableObject and then make a method who paste my values. But maybe somebody has a better idea??????????
Afaik you can use Instantiate also for cloning ScriptableObject on runtime! Only you can of course not use any component taking more then the original parameter (which makes sense).
And the same way as ScriptableObject.CreateInstance this will of course not create an asset but only a runtime instance.

GKRTree doesn't want to work at all, any other similar method?

I'm making a game, where i need to define the object in the radius of the explosion in certain radius. Firstly, i was making it through distance between all objects, but i saw that there is GKRTree class in GameplayKit. But after many tries, it doesn't want to work at all. It just returns empty array in any case. I want to know, are GKRTree class broken or what. If yes, are there any other method to do the same stuff as GKRTree in swift or github. Because i dont want to calculate distance, since it can be use a lot of cpu.
Thanks
Edit: I tried what is described in this answer https://stackoverflow.com/a/38655862/11687591, but it dont work. And there are no another solution about this problem. There is some links, where somebody is talking about broken gkrtree and there is no answer. https://www.reddit.com/r/swift/comments/63frk6/does_anyone_have_a_working_example_of_gkrtree/
https://twitter.com/StayOnTheMove/status/1067067053419520000?s=20
And that's all. One things that i've tried that i created 2 circles. One of them is not moving and in one position all the time. Another is moving to my touch position. Second is smaller than the other one. Larger is a little bit transparent so i can see other circle. I also use print() to see all things that happening in the code. And after all of that, even if there is clearly situation where one circle is inside other one, gkrtree.entities method don't work and it returns empty array.
For what it's worth, GamePlayKit.GKRTree is recently failing for me as of Xcode 11.5+. The following line,
import GameKit
class blah {
private var searchTree: GKRTree<RouteSegment>?
public init() {
searchTree = GKRTree.init(maxNumberOfChildren: 3)
}
}
Using a let expression also gets a nil value.
Edit:
The reason it was returning nil is because I didn't have GameplayKit in the linking phase of the project. Duh. By default, all the iOS frameworks are on the search path, which doesn't mean they will be available at runtime. I'm not sure why Apple chose this mechanism. When I traced the assembly code step into the init() function, I found it just returned nil; there must be some stubs in the API.
Solution for me: make sure that GameplayKit is in the linked binaries phase in the project settings.

Is it possible to modify a global variable in a nested if statement?

I'm trying to make a simple text based game thing just for fun/practice since I'm a dumb newbie and in my mind, I could make my code work IF I could just get a global variable to change when I want it to (if the player solves the puzzle correctly, it would change the answers to the questions, and you can continue through the game, if you can even call it a game).
I basically started with just stating computerNumber = computerNumber + 1 in order to change a whole bunch of other variables, then looked at youtube videos and some stack overflow things about variables in functions being able to effect global variables by adding "global" in front of them, so I made a function that looks like this
def function():
global computerNumber
computerNumber = computerNumber + 1
return
function()
but it still doesn't seem to reach the global variable, just changing the variable within the if statement. I could have sworn I put the project in here when I initially made this post (it's fairly small), but I'm also new to posting on stack overflow, so I don't know what I'm doing with this either I suppose.

Activating Inactive Same-Name Different-Tag Game Objects

For some reason, I cannot change the name of a game object (an avatar) but I need to have 2 different versions of it and activate them in code.
So, duplicating the avatar is not an option, but I still need to create an identical one and make a change in editor mode, so that based on a condition, whether one or the other is chosen.
It occurred to me, now that changing the name is not possible, perhaps I can give the other a different tag and activate the right one based on the selected scenario.
So, I checked out a few manual docs and some forum posts and came up with the following 3 alternatives to place in my Start() but none works:
void Start()
{
if ( GameObject.FindGameObjectWithTag("John") )
gameObject.FindGameObjectWithTag("John").SetActive(true);
if ( GameObject.FindWithTag("John") )
gameObject.FindWithTag("John").SetActive(true);
}
Can someone please help me understand what I am doing wrong and how I can achieve this: find an object that is not active (from among 2 inactive objects with the same name but different tags: one untagged and the other tagged as, say, John)
Couldn't be easier, just assign them to different variables
public GameObject johnCharacterOnLeft;
public GameObject johnCharacterWhoJoinsLater;
void Start()
{
johnCharacterOnLeft.SetActive(true);
johnCharacterOnLeft.Whatever(true);
johnCharacterOnLeft.Whatever(true);
johnCharacterOnLeft.Whatever(true);
johnCharacterWhoJoinsLater.SetActive(false);
johnCharacterWhoJoinsLater.Whatever(false);
johnCharacterWhoJoinsLater.Whatever(false);
...
}
Note, as a rule when you are learning, do not use Find. It's that simple. Use public variables and drag to connect in the inspector.
(If anyone reading does not yet know how to drag to connect in the inspector, check any basic tutorial.)
If you do want to find all objects with a certain tag:
GameObject[] allCats;
allCats = GameObject.FindGameObjectsWithTag("cat");
foreach (GameObject g in allCats)
Debug.Log("I found one, name is: " +g.name);
If you want to find one of those with a certain name you have to search through them all..
GameObject[] allCats;
allCats = GameObject.FindGameObjectsWithTag("cat");
foreach (GameObject g in allCats)
{
Debug.Log("I found one, name is: " +g.name);
if ( g.name == "Felix" )
{
Debug.Log("I did find Felix the cat");
g.Whatever ...
}
If you do want to find all objects with a certain name...
It's very important to understand that
...you just can't do that in Unity - it simply makes no sense.
Life's life that - Find is a hack you should never really use anyway, other than in rare situations. If you (for some reason?) need to "find" all game objects with a certain name, you have to simply look through every single thing in the scene (which is not particularly easy to do). You can easily google this. But there is, absolutely, no reason you would ever do this.
Note that, just one example .. say you had a number of "cat" thing in your scene. Very simply - nothing more complicated than this - you would have them all in the same "folder". (That is to say, all under the same holder game object.) That is just one incredibly simple approach to utterly avoid the sort of problem you're having.
Again there literally is no way to find "all game objects with the same name" - the Find call is a hack that should never have been in Unity; they explicitly don't have
And most importantly don't forget...Find doesn't work if inactive!
The Find call is a hack that should never have been in Unity: always remember it does not even work on inactive objects. Inasmuch as they threw in a "find name" concept, it's probably for the best that it doesn't work on inactive objects: but the whole thing is a shambles - just don't use "find", ever.
Particularly as a beginner just drag in the inspector - it's honestly that easy. (And again, in almost all cases your stuff will start inactive, so of course you have to do that since you can't "find" inactive stuff.)
(And a note - don't forget that if you're simply finding a "boss" type script, say your Scores or SoundEffects, never use find. Just do this easy idiom. )

Game: General Structure and Game Item Structure

I am making a graphically simple 3D game in C++ using DirectX. The main problem I am having is with how to structure some things efficiently. Right now I know my goal for certain areas but not how to ideally perform them.
For instance, right now I am storing all meshes and textures in an Asset class with enumerated definitions pointing to each asset. All meshes and textures are loaded when the game starts by creating an Asset object and initializing it. From there I load meshes and textures to objects by assigning the pointer given by the Asset object. Is this the best way to go about this?
A harder topic is that of items. For the sake of argument I am going to say we are dealing with scenery. Right now my scenery needs the following:
A name
A mesh
Textures (optional)
Flags (such as Destructible, Flammable, etc.)
Status (such as Burning, Locked, Cursed, etc.)
Abilities (things the object actually does, such as becoming damaged when burning)
The first 5 things on this list are simply variables. But abilities are bothering me. The first 5 can all exist in one item class. But what I do not know how to do is somehow attach abilities to the object.
For example; I want the object to have the "Fire Nova" ability. At the start of each turn, the object damages anything near it.
For me, this means each object would need a "Trigger_Phase_TurnStart()" or some similarly named method and would then need a new "Fire Nova" class with its own unique action for that trigger and its own extra variables (Damage, Range, etc). So now I have the base object class and a new Fire Nova class that inherits from it.
But now what if I needed an object that has Fire Nova and Frost Nova and also Slowing Aura and other such abilities. Basically I need a way to add triggered effects to an object without needing a new object class for each of them.
So by the end I would be able to have say:
(pseudo code of the object's components)
name = Elemental Orb
mesh = "Mesh_Sphere"
textures[] = "Tex_Ice", "Tex_Fire"
flags = OF_Destructible
status = SF_Cursed | SF_Burning
abilities[] = Fire_Nova, Frost_Nova, Slowing_Aura
And this orb would simply be the object class with all these attributes. The object would then activate each stored ability's trigger at the appropriate turn phase for any actions to perform.
Right now I am thinking I might need to make a class for each ability possessing every turn-phase or action trigger (inherited from a base ability class) and have them perform the appropriate action when the object calls them from it's array of abilities. Would this be the best way to do this?
As a separate issue. Some flags would require additional variables that would otherwise be unnecessary. For example, Destructible would mean the object would have health whereas without the flag it wouldn't need it, or an Openable item would need an array of contents. What would be a good way to ration these variables to when they are needed? I do not need every wall to have health and an empty contents array for example.
Finally. Assuming the bullet-listed attributes above are all an item needs, how might you suggest I best store them? To clarify, I would like to be able to write:
CreateItem(ITEM_CHAIR);
and have this return the created object with name, mesh, textures, flags, status and abilities. What structure might be suitable for achieving such an end effect?
To summarise:
Does my current Asset storage seem feasible?
What is the best way to create abilities to attach to the object class without making numerous separate object classes?
Is there a way to limit the variables (or at least memory usage) when the associated flag is not present?
What structure or format would be best for storing fixed item definitions?
Sorry if this is a little long winded. If you cannot answer all the questions then an answer to one would still be appreciated. Question two is probably the largest priority for me right now.
Thanks for your time :)
I want only answer question 2 and it looks like you need a decorator pattern. In OOP a decorator pattern is useful when you have many ingredients and wants to decorate an object, for example a pizza. Unfortunately you need to create for each ingredient a separate class hence I think you have the right approach. The good thing is that with the decorator pattern you can wrap the object over and over with abilites classes and call only one method at the end to do all the stuff.