Jump to content

Lua rocket example


Josh
 Share

Recommended Posts

I am leaning towards making each script attachment an "actor" that is self-contained. Actors perform game actions, and turn ordinary entities into interactive game objects. Actors do not share variables or functions. Entities themselves can have Lua functions and values attached to them, but this practice would be an exception. So an entity can have two "mover" actors, three "animation" actors, and one "cow" actor, and none of them interfere with one another.

 

To display it visually, the hierarchy in Lua would look like this:

entity={}
entity.actor[0]={}
entity.actor[0].health=100
entity.actor[0].name="Dave"
entity.actor[1]={}
entity.actor[1].speed=10
entity.actor[1].mood="Angry"
entity.actor[2]={}
entity.actor[2].openstate = true

If you have an entity and want to call an Open() function on all its actors, you would do this:

                for actor in entity.actor do
                       if actor.Open~=nil then
                               actor:Open()
                       end
               end

Some of these functions don't exist yet, but this code demonstrates how actor classes would work with a rocket 'actor':

self.damage = 25
self.speed = 10
self.force = 100

--Use physics to set body velocity
function actor:UpdatePhysics()
local v = self.entity:GetVelocity()
self.entity:AddForce((Vec3(0,0,self.speed)-v)/60)
end

--Explode on impact
function actor:Collision(collisionentity,position,normal,force)
self:Explode()
end

function actor:Explode()
local entity, aabb, list, actor, effect

--Create an AABB for the explosion volume
aabb = AABB()
aabb.min = self.entity.position - self.blastradius
aabb.max = self.entity.position + self.blastradius
aabb:Update()

--Get all entities in the explosion volume
list = GatherEntities(aabb)

--For each entity in the explosion volume, lets add some physics force and call the Hurt() function, if it exists
for entity in list do

	-- Calculate strength of effect based on distance from blast center
	effect = (1.0 - self.entity:GetDistance(entity,true)) / self.blastradius

	--Add force to the entity
	entity:AddForce(self.force * effect)

	--Now check all entity actors for a Hurt() function and call it, if present
	for actor in entity.actor do
		if actor.Hurt~=nil then
			actor:Hurt(self.damage * effect)
		end
	end
end

--And delete the entity
Delete(entity)
end

--Heck, lets add a Hurt() function
--If the rocket receives any damage at all, it will explode
function actor:Hurt(damage)
self:Explode()
end

  • Upvote 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

I think that looks good. I wouldn't call the scripts that can be attached "actors" though. I would simply call them what they are, scripts.

 

 

for actor in entity.actor do

if actor.Hurt~=nil then

actor:Hurt(self.damage * effect)

end

end

 

That seems like a very common task so would be better if it was enclosed in some kind of global helper function somehow like CallMethod("Hurt", dmg) or FindMethod("Hurt")(dmg) or something like that.

 

 

I think each "actor" or script should have a default name that gets assigned by the engine and it's the script name minus the extension, and then we should be able to FindScript("name") on any entity. FindEntity("name"):FindScript("name"):Hurt() or something like that.

 

The ideal way for doing this I think would be to have "actors" have exposed variables that we can set via the editor and it would do something like:

 

self.myentity = FindEntity("name")

Link to comment
Share on other sites

Ah, but you can have more than one script of the same type attached. It could handle multiple scripts of the same name if it creates tables on the entity and stores them like this:

 

entity.mover[0] = {}

entity.mover[1] = {}

entity.door[0] = {}

 

I don't know if calling the attached game object a "script" is accurate, because each one can have its own values, so it doesn't really correspond to a global file.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Especially because I might have an actor.script table, in which shared variables for each script file would be stored.

 

actor.script.whatever=3 --shared across all actors of this type

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

I think also that the word actor is misleading, because I would expect than a actor is a entity which contains the model.

Maybe the word activity would be more suitable, since a model can perform multiple activities at the same time: it can move, it can animate, it can shoot.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I'm not trying to compare Leadwerks to Unity 3D or anything, but for the sake of making sure I understand you accurately, I think it's safe ground. ;) This sounds a LOT like the system Unity has in place for dealing with scripts. You can attach a script to any node (and multiple scripts to the same node), and the same scripts to multiple nodes of different types. At runtime it just fires off certain, predetermined methods/functions (Object.Update, Object.OnClick, etc.) in each attached script at the appropriate time. Is this what you're trying to accomplish? If so, you've got me grinning. :)

There are three types of people in this world. People who make things happen. People who watch things happen. People who ask, "What happened?"

Let's make things happen.

Link to comment
Share on other sites

I don't know anything about Unity's scripting system, but multiple scripts were suggested a few months back and after thinking about it a while it seemed like a good idea.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Will there be an RunScript( script )/LoadScript( filename ) functionality also ?

There's ExecuteFile(). LoadScript / RunScript is a little weird, because that is not at all the way Lua works.

 

Around that line, copying existing entities and created other instances that have all the same scripts attached for dynamic creation via code.

For the attachments, that should be no problem. As far as getting a copy of all the values set in Lua, that might be problematic, because some things you would want shared, and some things you would want copies made.

 

I see this working out as you create prefabs, like in 3D World Studio. A prefab is an entity + whatever scripts are attached to it. Then you can call LoadPrefab() or maybe LoadEntity() to load the fully decked-out object, ready for use. So like if you had a flickering streetlight, you would just load the prefab, and have everything working immediately.

My job is to make tools you love, with the features you want, and performance you can't live without.

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...