Jump to content

Is there an easy way to set a "self.target" within a script automatically to player"?


Mordred
 Share

Recommended Posts

Hey guys,

 

since i had to do quite some work to get my script actually targeting the player i'm wondering if this is somehow easier achieved?

 

For e.g. if i define a script variable like the player HP i can predefine it with the value "100", is that possible with "self.target" too?

 

Oh: Before that happens...

i do not want to drag the player into the affiliated fiel in the script entity, i want to do this code wise. And i do not really want to have to bother arround with the range between the script entity and the player. Just a simple, playing, "self.target = set.player()" or so would be cool :)

Link to comment
Share on other sites

If you do not want to drag a player entity into a field, then your other option is to loop over all loaded entities looking for the player inside your other script.

 

Inside your start method:

 

for x=0,App.world:CountEntities()-1 do

local entity = App.world:GetEntity(x)

if entity:GetKeyValue("type") == "player" then

self.target = entity

end

end

 

The reason this works is because the "type" key was set to "player" in the player script. You can do this for any loaded entity.

 

Note that there is this sort of "hidden" dependency you are creating by doing this with this script. This requires that an entity in your scene has a key value "type" of "player". It may not look bad now with 1 thing, but if you do this enough your scripts and the indirect dependencies can be confusing for others, and maybe even yourself in a couple weeks.

 

You could wrap this up in a nice function like FindEntityByName() where you would return a table of entities (because names don't have to be unique), or FindEntityByTag(), where it has a key of "tag" with a value (sort of like Unity does). The efficiency of this is not great though. Be sure to try and stick to this only in the Start() method as it loops over all entities in the world. Of if you bailed out once you found yours, you don't know how many iterations it will need to get to the one you need. Direct linking via the editor is faster.

Link to comment
Share on other sites

Okay, thank you Rick, so it might occur "slow" in the first place, bit later on it might be simply better to attach the "player" script manually, because: the more often i use that the longer the iteration lasts since it has do to the same work several times. Did i understand it correct?

 

I was hoping for a builtin function that wouldn't need to "check all entities" at all. Well, anyways, you did answer my question, thanks!

Link to comment
Share on other sites

Normally you would want to only loop over the entities to find the one you want in the Start() function of the scripts and then save it in a variable for later use. Looping over them in an update loop won't be the end of the world but slower.

 

The way you avoid checking all entities to find the one you want is by connecting them in the editor via a script parameter :), which you said you wanted to avoid.

Link to comment
Share on other sites

Well , it's great do drag and drop player on some script slot , why ?

 

1) The slot having "player" on drag and drop slot avoids you to go throught the loop that will be more slow

2) Any game can have it's own programmer naming covention like "player", "car_player", "plane"

3) Some games can be RTS or tactical team based game, so you won't control "player" , but many units

 

A solution could be in App.lua to have a global variable pointing to player character , perhaps a drag and drop slot or a loop search function in start function of App.lua

This way player variable would be stored one time for all and could be used by any script directly without needing drag and drop or loop function.

Or am i wrong ?

Stop toying and make games

Link to comment
Share on other sites

A solution could be in App.lua to have a global variable pointing to player character , perhaps a drag and drop slot or a loop search function in start function of App.lua

This way player variable would be stored one time for all and could be used by any script directly without needing drag and drop or loop function.

 

Yeah, that is another solution, but again it's going down the global path. You'll have to know/remember that App.lua is at a higher level than a loaded map, so when you load a new map from the same game session that variable that's pointing to "player" will no longer be valid (because you would have had to free the current world to load a new map) and you'll have to reassign it. I know it's easy to do and when your project is small it doesn't seem complicated, but this is really one of those things where you have to watch out for. The last thing you want is to get far in your game and have to restructure major parts because you start finding it confusing because you have global variables everywhere. When newer to programming it's one of those things that's hard to understand what the issue is with globals until you've experienced it themselves.

  • Upvote 1
Link to comment
Share on other sites

I agree global variables that can be a pain.

But as "player" will be general for your game , you have just to have in each map some "player" entity simply.

This could save to have to drag and drop "player" on each NPC, interactive level stuff.

Also in App.lua you could at each loading of map swicth "player" to "player_car" for example depending on map.

 

If you keep on each map "player" as character or vehicle, no problem at all.

 

If your game is some entire FPS like "Duke Nukem Forever" as example, well you'll have always "player" could you be in FPS or driving a buggy or interacting.

This is a great shortcut when you "pilot" one NPC or vehicle or whatever, to have "player" in each map, but not valid for RTS, squad based tactical for example.

 

This could be some tutorial or WIKI if i have time, for people having "player" in each map and just wanting faster workflow and direct "player" access in their Lua script.

Stop toying and make games

Link to comment
Share on other sites

I would agree that player could be setup this way. Although how your NPC's interact and "find" the player often doesn't require having to know the player object right away on startup. Darkness Awaits, along with many other game styles, finds the player via a bounding box check around the NPC (aggro range).

 

If you have some kind of spawner(s) that makes NPC's (think L4D when horde is alerted), the spawner would only need to know about the player and pass that knowledge on to the NPC's it creates so it's assigning that information to a lot less entities in your scene. When you shoot at a zombie the "bullet" information can hold the "shooter" which would be the player and the zombies could be informed that way.

Link to comment
Share on other sites

Why needing to find it each game frame update when you can have it directly.

Even Spawners could have it directly.

Well i think this is the way i would go , have player as global variable to keep it simple without drag and drop on all NPC and all doors and other in game traps , systems, collision zones.

Stop toying and make games

Link to comment
Share on other sites

Why needing to find it each game frame update when you can have it directly.

 

Because this is how "aggro" works, and it doesn't have to be each frame. A timer could make it look every 250ms or something. You don't need to drag the player in all of those things. Collision zones for example fire a collision event which passes the entity that collided with it. You use that to check if it's the player.

 

Don't say I didn't warn you about the evil ways of globals :)

Link to comment
Share on other sites

I think the way YouGroove explained might be quite good for my idea's. I do not want to use that "Player" variable for mobile entities (like hostile mobs or os) but for interactive stationary objects. Say if i want to cut down a tree i want to have the tree automatically know that the result (for e.g. "you choped 10 logs") pass the values to the player without having to bother attaching the script to the whole forest at all. Hostile entities are another thing, here i have to say that i'm gonna use the way like in darkness awaits. That's how i actually managed to get my first script in the other topic up n running. Besides that i could use that script for all interactive stuff so it's just "checking for the player in the proximity" once i "use" the object (using function Script:use()). Anyways, i have to take a deeper look into those options. Thanks for showing the possibilitys to me :)

Link to comment
Share on other sites

Say if i want to cut down a tree i want to have the tree automatically know that the result (for e.g. "you choped 10 logs") pass the values to the player without having to bother attaching the script to the whole forest at all.

 

How do you know the player is chopping a tree then? The player needs to interact with the tree model and you need to know the thing the player is interacting with is a tree. Generally with this you'll do a raycast from the player toward the middle of the screen (if in first person). Then when it collides with an entity you can see how long the ray is to determine if you are close enough. But then you need to know what model it collided with somehow, so that model needs to identify itself. If trees have max wood count then each tree needs to hold this value. This is why a script attached and make it a prefab so you can easily just place them in the world, would probably be a decent way to go about that.

Link to comment
Share on other sites

Well, i gonna have to look into it :) i'm not really sure how the raycasting thing work right now, but i already watched a tutorial from Aggro that did explain it quite good, so i might have to take another look into it :)

 

Again my thanks for all your suggestions, i very much appreciate all your help!

Link to comment
Share on other sites

Quote

 

i do not want to drag the player into the affiliated fiel in the script entity, i want to do this code wise.

Can I ask why?

 

Oh, hey Josh, it seems i did oversee your question. Sorry 'bout that. In case you're still curious why i do not want to do it on my own is, that i do not want to bother attaching "targets" to maybe dozens or hundreds of (stationary) entitys in the gameeditor. But it seems, that creating one entity and saving it as a prefab does save the "target" somehow (even though, the "target" value is shown as empty, it somehow did work without the need to attach the player again). It's just, i'm lazy and looking for the easiest way to work around that :)

Link to comment
Share on other sites

i agree to Rick.

 

chopping wood on a tree is not much different than shooting a gun at an enemy.

 

But always try to have it as general as possible.

What i mean with that try to avoid calling a function inside the player script from the entity the player has hit.

This will save you from having to change all entity scripts when you change something small in your player.

 

So just return to the player what the player should actually change. like adding 10 wood and don't change the player.wood value from inside the tree.

 

i hope that was understandable.

Link to comment
Share on other sites

Yea beo6, it is :) Thanks, well, i did start a bit, but while i was coding i made actually several changes and tried diff. aproaches already, i guess that'll happen quite a lot when you're still very new to all this :) Anyways, it makes fun! So it shall continue.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...