DSabre 2332 Posted March 1, 2016 This is a tiny guide or actually a template for setting up an aircraft. It was thrown together in a few minutes and is full of flaws, so use at your own risk. I am not answering any complaints or suggestions for this one. Here it is, you may use, adapt or otherwise mess around with it - just change the addon prefix and paths please. (a playable version of this can be found in my steamworkshop) Let's get started. First you have to set up your Arma Tools. There are guides around for that, so this is not covered here. Once this is done get my small example plane here. You can use this tiny sketch of an addon as a template for your plane. Now I am going to very briefly explain what parts are doing what, and what the files do. Open your ultralight.p3d in objectbuilder. I suggest using the four views view (F9). Somewhere you will have this window with the LODs. Click the link to check what they are for. To make it work on a basic level these LODs are enough. You could even do without ShadowVolume, FireGeometry and Wreck if they confuse you. The edit layer is a convenient way to store parts. Or more useful even to work on some parts you can cut out of your main model to work on them separatly without dealing with all the other parts. That makes selecting parts a lot easier. So that one is not really needed either. Then there is this window showing your named selections. Named selections are important for hidden selections, clan tags or animated parts among other uses like weapons, firing animations or pilots etc. You can make new selections by selecting parts in your model and right clicking here. It is a good practise to make names for parts, even if you do not animate them later (examples: engine parts, glass parts, cockpit parts, interior, metal, wood, etc) It will make selecting and working on things a lot easier. An important feature is the ability to redefine the named selection. You select a part of the model, say your elevator, then you rclick the named selection for elevator, in this example the czech word for it (vejskovka). Then you can use redefine to redefine the selection name. This is important if you exchange the model of the aircraft. For Arma to know what part should be animated as elevator, the named selection has to be assigned to the appropiate part. Actually you could just delete the contents of the LOD 1 and copy/paste your own plane in here now. Then reselect the wheels, the elevator, the ailerons and the rudder and redefine their named selections. You can give it any name you can think of either, if you want to use some other language. It is only necessary to use the same names in the model.cfg This brings us to the next part, the model.cfg: click for the model.cfg class CfgSkeletons { class Default { isDiscrete = 1; skeletonInherit = ""; skeletonBones[] = {}; }; class Vehicle : Default {}; class Plane: Vehicle {}; class ultralightSkeleton: Plane { skeletonInherit = "Plane"; skeletonBones[] = { "vejskovka","", "smerovka","", "wheel_1","", "wheel_2","", "wheel_3","", "stick_pilot","", "pedal","", "rotor","", "vrtule","", "vrtule blur","", "vrtule hide","vrtule", }; }; }; class CfgModels { class Default { sectionsInherit=""; sections[] = {}; skeletonName = ""; }; class Vehicle: Default {}; class Plane : Vehicle {}; class ultralight: Plane { skeletonName="ultralightSkeleton"; sections[]= { "clan", // for the clan squad xml pic add a selection to the model and name it clan (can be 2d plane) "clan_sign", // same here, add a plane to the model called clan_sign "vrtule staticka", "vrtule blur", "camo1", "camo2", }; class Animations { class Elevator { type="rotation"; source="elevator"; selection="vejskovka"; axis="osa vejskovky"; minValue=-1; maxValue=1; angle0="rad 30"; angle1="rad -30"; }; class Rudder { type="rotation"; source="rudder"; selection="smerovka"; axis="osa smerovky"; minValue=-1; maxValue=1; angle0="rad 35"; angle1="rad -35"; }; class wheel_1 { type="rotation"; source="wheel"; selection="wheel_1"; axis="wheel_axis"; memory=1; sourceAddress = "loop"; minValue = 0.0; maxValue = 1.0; angle0=rad 0; angle1=rad -360; }; class wheel_2: wheel_1 { selection="wheel_2"; axis="wheel_axis"; }; class wheel_3: wheel_1 { selection="wheel_3"; axis="wheel_axis_3"; }; class Stick_Pilot_Bank { type="rotation"; axis="stick_pilot_ail_axis"; source="aileron"; selection="stick_pilot"; minValue=-1; maxValue=1; angle0="rad -10"; angle1="rad 10"; }; class Stick_Pilot_Dive { type="rotation"; axis="stick_pilot_ele_axis"; source="elevator"; selection="stick_pilot"; minValue=-1; maxValue=1; angle0="rad -10"; angle1="rad 10"; }; class rotor { type="rotation"; source="rotor"; selection="vrtule"; axis="osa vrtule"; sourceAddress="loop"; minValue = 0.0; maxValue = 0.2; angle0=rad 0; angle1=rad 360; }; class rotor_hide { type="hide"; source="rpm"; selection="vrtule hide"; HideValue = "0.5"; }; class propeller_blur { type = "rotation"; source="rotor"; selection="vrtule blur"; axis="osa vrtule"; sourceAddress="loop"; minValue = 0.0; maxValue = 0.2; angle0=rad 0; angle1=rad 90; }; class propeller_blur_hide { type="hide"; source="rpm"; selection="vrtule blur"; unHideValue = "0.5"; }; }; }; }; I can't really recall how i made this model.cfg. It is probably a copy and paste job from some tutorials and my Arma 2 ports (An-2, Camels etc). Anyway it works for me. even if it may not be perfect or the right way to do it. So the first interesting part here is this: "vejskovka","", "smerovka","", "wheel_1","", "wheel_2","", "wheel_3","", "stick_pilot","", "pedal","", "rotor","", "vrtule","", "vrtule blur","", "vrtule hide","vrtule", These are the animated parts. Note that there is a named selection, and then usually an empty "", after it. That is the parent selection/bone (?). Whatever the name is. The thing in the 2nd set of "" is the parent part. So normally there is none, in some cases you may have one as in gear parts or here with the vrtule or propeller. The "virtule hide" part, the part that gets hidden if the prop moves is the child of the complete part, or "vrtule" in this case. You can exchange the names for prop and prop hide if you want. Just have to make sure the names match your model. Having a parent means that your child part will be connected and move together in sync with the parent part. Important to know: This also works for memory points or landcontact points! So if you have an animated gear you can animate the landcontact part by making it a named selection and adding it to the list with a parent part matching your gear. You don't even have to make an entry further down below because it is now connected to your parent part : ) The next interesting part is this: "clan", // for the clan squad xml pic add a selection to the model and name it clan "clan_sign", // same here, add a plane to the model called clan_sign "vrtule staticka", "vrtule blur", "camo1", "camo2", these are selections that will have some kind of special texture. clan is the part that will get your squad.xml motto, clan_sign the squad.xmp paa picture. vrtule parts have to be listed here as well I think, there might be some other ways of doing this actually. camo1 and camo2 can be used for hidden selections, which you can apply in the config. Remember to assign some parts in your p3d lod 1 as camo1 if you want to use this feature. You can have as many as you want i think, so far i didn't use more than five and that worked. Now we get to the actual animation part: class Animations { class Elevator { type="rotation"; source="elevator"; selection="vejskovka"; axis="osa vejskovky"; minValue=-1; maxValue=1; angle0="rad 30"; angle1="rad -30"; }; ... This here tells Arma how to move your selection you made for your elevator. The classname can be anything i believe, it makes sense to use some sensible name though. Here you see that the selection called vejskovka will be animated by the source (scroll down to animation sources) "elevator" and move along the axis "osa vejskovky" with some angles and values. Play around to see what happens. The new information here is the axis "osa vejskovky". The axis is defined in our p3d. So back to oxygen/object builder and click the memory LOD. The memory LOD contains the axis and other points like where the driver has to stand to get the "get in" action among others. So here you can see there is a named selection "osa vejskovky" containing 2 points making up the elevator movement axis. To add points click somewhere and press insert. Add another, select both and you can give them a name as explained before. Voila you have a new axis you can use to animate some part. What is left? The Geometry LOD is worth a look. The example is really an example of how not to do it. It is a bad copy/paste job. I think i took it from the antonov or camel. Well basically you could make a new box, triangulate it (menu structure) (DONT!! triangulate your GEO LOD. Only for your shadow lod : ) ) and make it's edge sharp (key U). In the menu Structure you should also find new components under Topology if you add any. The wheels shape plays an important part too. If you get in trouble they might be worth a look. Well this is a super brief run through, now let's have a look at the config. clicky to see #include "basicdefines_A3.hpp" class CfgPatches { class sab_ultralight { author = "[Dust]Sabre"; authorUrl = ""; version = 0.11; units[] = {"sab_ultralight"}; // Add the names here for visibility in ZEUS! requiredAddons[] = {}; // add required addons here }; }; class CfgVehicles { class Air; class Plane: Air { class Sounds; class AnimationSources; }; class sab_ultralight_BASE : Plane { displayName = "sab_ultralight"; model = "sab_ultralight\ultralight.p3d"; // path to p3d of the model icon = "sab_ultralight\data\icomap_ultralight_ca.paa"; // map icon picture = "sab_ultralight\data\icomap_ultralight_ca.paa"; // icon of you sitting inside, or someone else mapSize = 10; // size of icon on map simulation = "airplanex"; // airplane or airplaneX (physX) crew = "C_man_shorts_2_F"; cabinOpening = false; gearRetracting = false; flaps = false; // pilot *************************** driverCompartments = "Compartment1"; driverAction = "Plane_Fighter_03_Pilot"; driverIsCommander = true; ejectDeadDriver = true; hideWeaponsDriver = true; hideWeaponsCargo = true; memoryPointsGetInDriver = "pos driver"; memoryPointsGetInDriverDir = "pos driver dir"; driverLeftHandAnimName = ""; driverRightHandAnimName = "stick_pilot"; driverLeftLegAnimName = ""; driverRightLegAnimName = ""; // Armor, Weapons, Vulnerability, etc *************************** radarType = 0; enableManualFire = false; fuelCapacity = 600; fov = 0.7; maxFordingDepth = 0.3; passThrough = 0.7; crewVulnerable = "true"; accuracy = 0.2; cost = 2000; laserScanner = 0; gunAimDown = 0.029000; minFireTime = 30; threat[]={0.1, 1, 0.7}; type=VAir; ejectSpeed[] = {0, 0, 0}; armor = 10; damageResistance = 0.00278; destrType = DestructWreck; irScanRangeMin = 50; irScanRangeMax = 5000; irScanToEyeFactor = 2; damageEffect = "DamageSmokePlane"; weapons[] = {}; magazines[] = {}; // textures, camera *************************** hiddenSelections[] = {"camo1"}; extCameraPosition[] = {0,0.5,-15}; // flight, swim and drive Model *************************** #include "ultralightFlightmodel.hpp" // sounds *************************** insideSoundCoef = 0.8; nameSound = "plane"; soundGetIn[]={"\sab_ultralight\data\sounds\close",db--15, 1.0}; soundGetOut[]={"\sab_ultralight\data\sounds\open",db--15, 1.0}; soundDammage[]={"\sab_ultralight\data\sounds\alarm_loop1", db-5, 1}; attenuationEffectType = "OpenHeliAttenuation"; soundEngineOnInt[] = {"A3\Sounds_F\air\UAV_02\UAV_02_start_ext", 0.707946, 1.0}; soundEngineOnExt[] = {"A3\Sounds_F\air\UAV_02\UAV_02_start_int", 0.707946, 1.0, 400}; soundEngineOffInt[] = {"A3\Sounds_F\air\UAV_02\UAV_02_stop_int", 0.707946, 1.0}; soundEngineOffExt[] = {"A3\Sounds_F\air\UAV_02\UAV_02_stop_ext", 0.707946, 1.0, 400}; class Sounds { class EngineLowOut { sound[] = {"A3\Sounds_F\air\UAV_02\UAV_02_low_ext", db-3, 1.0, 450}; frequency = "1.0 min (rpm + 0.5)"; volume = "camPos*(rpm factor[0.95, 0])*(rpm factor[0, 0.95])"; }; class EngineHighOut { sound[] = {"A3\Sounds_F\air\UAV_02\UAV_02_high_ext", db0, 1.0, 650}; frequency = "(rpm factor[0.5, 1.0])"; volume = "camPos*(rpm factor[0.2, 1.0])"; }; class ForsageOut { sound[] = {"A3\Sounds_F\air\UAV_02\UAV_02_forsage_ext", db1, 1.0, 900}; frequency = "1"; volume = "engineOn*camPos*(thrust factor[0.6, 1.0])"; cone[] = {3.14, 3.92, 2.0, 0.5}; }; class WindNoiseOut { sound[] = {"A3\Sounds_F\air\UAV_02\noise", db -10, 1.0, 150}; frequency = "(0.3+(1.005*(speed factor[1, 50])))"; volume = "camPos*(speed factor[1, 50])"; }; class EngineLowIn { sound[] = {"A3\Sounds_F\air\UAV_02\UAV_02_low_int", db0, 1.0}; frequency = "1.0 min (rpm + 0.5)"; volume = "(1-camPos)*(rpm factor[0.95, 0])*(rpm factor[0, 0.95])"; }; class EngineHighIn { sound[] = {"A3\Sounds_F\air\UAV_02\UAV_02_high_int", db0, 1.0}; frequency = "(rpm factor[0.5, 1.0])"; volume = "(1-camPos)*(rpm factor[0.2, 1.0])"; }; class ForsageIn { sound[] = {"A3\Sounds_F\air\UAV_02\UAV_02_forsage_int", 0.630957, 1.0}; frequency = "1"; volume = "engineOn*(1-camPos)*(thrust factor[0.6, 1.0])"; }; class WindNoiseIn { sound[] = {"A3\Sounds_F\air\UAV_02\noise", db -20, 1.0}; frequency = "(0.3+(1.005*(speed factor[1, 50])))"; volume = "(1-camPos)*(speed factor[1, 50])"; }; }; class Exhausts { class Exhaust1 { position = "exhaust"; direction = "exhaust_dir"; effect = "ExhaustsEffect"; }; }; class AnimationSources { }; class UserActions { }; class Damage { tex[]={}; mat[]={}; }; class Reflectors { class Main { color[] = {1900, 1800, 1700}; /// approximate colour of standard lights ambient[] = {5, 5, 5}; /// nearly a white one position = "L svetlo"; direction = "L svetlo dir"; hitpoint = "L svetlo"; selection = "L svetlo"; size = 1; /// size of the light point seen from distance innerAngle = 100; /// angle of full light outerAngle = 179; /// angle of some light coneFadeCoef = 10; /// attenuation of light between the above angles intensity = 1; /// strength of the light useFlare = true; /// does the light use flare? dayLight = false; /// switching light off during day saves CPU a lot flareSize = 1.0; /// how big is the flare class Attenuation { start = 1.0; constant = 0; linear = 0; quadratic = 0.25; hardLimitStart = 30; /// it is good to have some limit otherwise the light would shine to infinite distance hardLimitEnd = 60; /// this allows adding more lights into scene }; }; }; class MarkerLights { class sab_RedStill { name = "PositionLight_red"; color[] = {1.0, 0.1, 0.1, 1}; ambient[] = {0.1, 0.01, 0.01, 1}; brightness = 0.05; blinking = false; }; class sab_GreenStill { name = "PositionLight_green"; color[] = {0.1, 1.0, 0.1, 1}; ambient[] = {0.01, 0.1, 0.01, 1}; brightness = 0.05; blinking = false; }; class sab_WhiteCollision { name = "CollisionLight"; color[] = {1.0, 1.0, 1.0, 1}; ambient[] = {0.1, 0.1, 0.1, 1}; brightness = 0.03; blinking = true; }; }; class TransportMagazines { }; class TransportItems { class _xx_FirstAidKit { name = "FirstAidKit"; count = 1; }; }; class TransportBackpacks { }; class TransportWeapons { }; class Library { libTextDesc = "Ultralight"; }; }; class sab_ultralight: sab_ultralight_BASE { author = "[Dust]Sabre"; scope = public; displayName = "Ultralight"; side = 3; faction = CIV_F; vehicleClass = "air"; hiddenSelectionsTextures[] = {"sab_ultralight\data\texture.paa"}; crew = "C_man_shorts_2_F"; weapons[] = {}; magazines[] = {}; }; }; I won't go into much details here. Just check here. You may notice that I've made a special flightmodel.hpp. There is one thing I want to point out there: driveOnComponent[] = {"wheels"}; This tells arma what parts of the model will be touching the ground. define these in geometry LOD. Wheels are tricky. Errors might cause stuck planes, planes not reaching reasonable speeds, taking damage, etc. One important aspect I've noticed is that it seems to work better if the landcontact points are below the actual parts. If your wheels are not listed in this array or you didn't make a selection called "wheels" that includes all wheels like I did here, your plane will be stuck : ) Well that's it for now. have fun PS: Actually I din't want to, but now I improved some parts. Maybe I will even continue to update this every now and then. 8 Share this post Link to post Share on other sites
jetSonicSVK 9 Posted March 1, 2016 Thank you Sabre! Good staring point for new modders like me. Again thank you an keep up the good work. APPRECIATE IT! Share this post Link to post Share on other sites
hnchmc 125 Posted March 5, 2016 Awesome Sabre! This helps a lot with modding. Love the ultralight :) Share this post Link to post Share on other sites