Jump to content
sarogahtyp

[Code Snippet] create method library - CreateVehicle, DeleteVehicle (Arma 3 similar)

Recommended Posts

What I began on my current AR project is to create a tool class with methods that make me some things easier.

In this case I show how to create an easy to use  CreateVehicle and a DeleteVehicle method with overloaded argument lists. Which just means that you can have different parameter syntaxes as known from various Arma 3 commands.

 

I created a new script file in the newly created folder MyProject/scripts/GameCode/Tools according to the AR directory structure as I understand it^^. I named the file SaRo_Tools.c - this file will contain the class with my tools methods.

 

What do I have to do when spawning a vehicle without that tools class?

Something like this:

Spoiler

		//prepare resource for spawning using prefabs resource name
		Resource resourceArmedHumvee = Resource.Load ("{DD774A8FD0989A78}Prefabs/Vehicles/Wheeled/M998/M1025_armed_M2HB_MERDC.et");
		
		//get source by resource
		IEntitySource sourceArmedHumvee = SCR_BaseContainerTools.FindEntitySource(resourceArmedHumvee);
		
		//spawn params object creation
		EntitySpawnParams paramsArmedHumvee = new EntitySpawnParams();

		//get spawn location somwhere behind user entity
	    vector spawnPosition = pUserEntity.CoordToParent( Vector (0, 0, -15) );
		
		//assign spawn position to params object
		paramsArmedHumvee.Transform[3] = spawnPosition;
		
		//snap spawn position to ground
		SCR_Global.SnapToTerrain(paramsArmedHumvee.Transform, GetGame().GetWorld(), true);
		
		float scaleArmedHumvee;
		
		sourceArmedHumvee.Get("scale", scaleArmedHumvee);
		
		if ( scaleArmedHumvee != 1.0) SCR_Math3D.ScaleMatrix (paramsArmedHumvee.Transform, scaleArmedHumvee);		
		
		// spawn Hum-Vee using already prepared prefab resource and  params object
		IEntity armedHumvee = GetGame().SpawnEntityPrefab(resourceArmedHumvee, GetGame().GetWorld(), paramsArmedHumvee);

 

 

Now instead of doing this we create our tools class which does most of this automatically:

 

Spoiler

class SaRo_Tools
{
 	//spawning vehicle using resource name and spawn position vector
 	static IEntity CreateVehicle (string resourceName, vector spawnPosition)
 	{
		//prepare resource for spawning using prefabs resource name
		Resource spawnResource = Resource.Load ( resourceName );
		
		//get source by resource
		IEntitySource spawnSource = SCR_BaseContainerTools.FindEntitySource(spawnResource);
		
		//spawn params object creation
		EntitySpawnParams spawnParams = new EntitySpawnParams();

		//assign spawn position to params object
		spawnParams.Transform[3] = spawnPosition;
		
		//snap spawn position to ground
		SCR_Global.SnapToTerrain(spawnParams.Transform, GetGame().GetWorld(), true);
		
		float scale;
		
		spawnSource.Get("scale", scale);
		
		if ( scale != 1.0) SCR_Math3D.ScaleMatrix (spawnParams.Transform, scale);		
		
		// spawn vehicle using already prepared prefab resource and  params object
		return GetGame().SpawnEntityPrefab(spawnResource, GetGame().GetWorld(), spawnParams);
 	}

 	//spawning vehicle using resource name, an Entity object where to spawn close at and a position vector relative to that entity
	static IEntity CreateVehicle (string resourceName, IEntity nearbyEntity, vector relSpawnPosition)
	{
     	vector spawnPosition = nearbyEntity.CoordToParent(relSpawnPosition);
      	return CreateVehicle (resourceName, spawnPosition);
    };
};

 

 

Now you have 2 easy methods to spawn a vehicle:

IEntity	vehicle1, vehicle2;

//1st method using resource name and spawn position
vehicle1 = SaRo_Tools.CreateVehicle("{DD774A8FD0989A78}Prefabs/Vehicles/Wheeled/M998/M1025_armed_M2HB_MERDC.et", Vector(1288.93, 0, 766.7));

//2nd method using resource name, an existing entity and a position vector relative to that entity
vehicle2 = SaRo_Tools.CreateVehicle("{DD774A8FD0989A78}Prefabs/Vehicles/Wheeled/M998/M1025_armed_M2HB_MERDC.et", someEntity, Vector (0, 0, -15)); //spawns 15m behind someEntity

 

Maybe I did some mistakes in this post because I did write it out of my mind partially. But I ll validate, expand and edit it if Im at home...

Deletion methods will be done then as well

 

 

EDIT:

 

to get this done, I also added 2 entity deletion methods to the tools class. I just post those 2 methods and not the CreateVehicle methods from above again although they are in that class:

Spoiler

class SaRo_Tools
{
  
   //CreateVehicle methods are here
  
  
    // deleting entity (and its children) using its ID
    static void DeleteVehicle (EntityID entID)
	{
	 SCR_EntityHelper.DeleteEntityAndChildren( GetGame().GetWorld().FindEntityByID (entID) );
	}
	
    // deleting entity (and its children) using its entity object
	static void DeleteVehicle (IEntity entity)
	{
	 SCR_EntityHelper.DeleteEntityAndChildren(entity);
	}
};

 

 

Now you have 2 easy methods to delete an entity:

//1st method delete using the entity ID
SaRo_Tools.DeleteVehicle ( SaRo_BMHQ01MenuBaseClass.camoNetID );

//2nd method delete using the entity itself
SaRo_Tools.DeleteVehicle ( someEntity );

 

Now YOU know how to build an own tools library class and you also know how to overload class methods. Its your turn to create more methods that way to get things a bit easier for you...

  • Like 2

Share this post


Link to post
Share on other sites

I like it! 

 

My critique would be swapping the string out for ResourceName type, though I am curious if the engine has an implicit conversion between the two? 

 

Otherwise, if we think about a mission-creator perspective we'd want full flexibility. Without the need to update a script over a resource path just to swap something out. Something like the following I believe will be, is, or should be (I have no idea) the standard for assigning these 'Resources'.  Which would then trickle down to tools like you made which might need to use ResourceName instead of a string. Perhaps an overload which uses it instead of string?

 

This is a snippet from a project I'm working on.

[Attribute("{B3E7B8DC2BAB8ACC}Prefabs/AI/Waypoints/AIWaypoint_SearchAndDestroy.et", UIWidgets.ResourceNamePicker, params: "et", category: "Waypoints", desc: "When attacking, AI are assigned this waypoint")]
private ResourceName m_AttackWaypointPrefab;

 

 

  • Like 1

Share this post


Link to post
Share on other sites

@sarogahtyp Thank you for this.

I was looking at setting up something similar to have common functions readily available; I find the extreme encapsulation in OOP to be, frankly speaking, a pain in the ass.

  • Like 1

Share this post


Link to post
Share on other sites
45 minutes ago, Badger 2-3 said:

My critique would be swapping the string out for ResourceName type, though I am curious if the engine has an implicit conversion between the two? 

 

ResourceName is a class just inherited from string. It has just one additional method which is GetPath() and with that you are able to get the Path of the entity ("Prefabs/Structures/Military/CamoNets/US/CamoNet_Large_US.et") as string when providing the Prefab ID ( "{CD8641F8E583489F}" ).

 

Like this:

ResourceName resourceName = "{CD8641F8E583489F}";
Print(resourceName); //   SCRIPT       : ResourceName resourceName = '{CD8641F8E583489F}'
Print(resourceName.GetPath()); 		// SCRIPT       : Prefabs/Structures/Military/CamoNets/US/CamoNet_Large_US.et

 

  • Like 1

Share this post


Link to post
Share on other sites

Didn't occur to me to open ResourceName and see that 😅oops. Never mind what I was rambling on about lol. 

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×