Ejemplo n.º 1
0
    //CKeyHook _oKeyHook_ThighSpread;
    //---------------------------------------------------------------------------	CREATE / DESTROY
    public override void OnStart_DefineLimb()
    {
        _nDrivePos = 0.5f * C_DrivePos;             // Weaken the leg pin drive over default

        //=== Init Bones and Joints ===
        CJointDriver oJointPelvis = _oBody._oActor_Pelvis._oJointExtremity;
        _aJoints.Add(_oJointThighBend 	= CJointDriver.Create(this, oJointPelvis,	    _sSidePrefixL+"ThighBend",      15, 3.0f, -115, 035, 000, 085, 1));	// X = Leg forward (-115) / back (35), Z = Thigh split (85) / together (20)  ###BAD: Super-important thigh split needed same value for thigh together makes no sense!  ###IMPROVE: 2nd joint?
        _aJoints.Add(_oJointThighTwist  = CJointDriver.Create(this, _oJointThighBend,	_sSidePrefixL+"ThighTwist",     20, 2.0f, -000, 000, 075, 000, 1));	// Y = Thigh twist -75 to 75 Ok
        _aJoints.Add(_oJointShin	    = CJointDriver.Create(this, _oJointThighTwist,	_sSidePrefixL+"Shin",	        10, 2.0f, -011, 155, 015, 005, 1));	// X = Knee bent (+155) or backward (-11),  Y = Knee rotate -25 to 10 with compromise at 15, Z = Knee side-to-side -5 to 5
        _aJoints.Add(_oJointFoot	    = CJointDriver.Create(this, _oJointShin,		_sSidePrefixL+"Foot",	        15, 1.0f, -025, 010, 020, 040, 1));	// X = Foot up (-40) and down (+75), inward -25 to +10, twist -35 to 15:			###IMPROVE: FootX not up/down!!  ###IMPROVE: 2 joints?  ###PROBLEM: Foot up down on Z with poor bending along down
        _aJoints.Add(_oJointMetatarsals = CJointDriver.Create(this, _oJointFoot,		_sSidePrefixL+"Metatarsals",	20, 0.5f, -000, 000, 020, 012, 1));	// X = Metatarsals left/right = useless, Y = twist -20 to 20, Z = foot bend -12 to 12
        _aJoints.Add(_oJointExtremity   = CJointDriver.Create(this, _oJointMetatarsals, _sSidePrefixL+"Toe",	        20, 3.0f, -000, 000, 020, 050, 1));	// X = Toes bend backward (-45) to forward (65),  Y = Toe twist -20/20, Z = meaningless   ###IMPROVE: Rotate axe?  ###CHECK: Toe mass??

        _oJointShin._oConfJoint.targetRotation = Quaternion.Euler(-160, 0, 0);		//###WEAK: Set knee default position so it can easily bend (with very week drive)		//###SOON: Proper bending of knee calculations from height

        //=== Init Hotspot ===
        if (_eBodySide == 0)            //###IMPROVE: Rediculously long path... switch to 'search for bone' (would not be as fast tho)
            _oHotSpot = CHotSpot.CreateHotspot(this, _oBody._oBodyBase.FindBone("chestUpper/chestLower/abdomenUpper/abdomenLower/hip/pelvis/lThighBend/lThighTwist/lShin/lFoot/lMetatarsals/lToe"), "Left Leg", true, new Vector3(0, 0, 0));
        else
            _oHotSpot = CHotSpot.CreateHotspot(this, _oBody._oBodyBase.FindBone("chestUpper/chestLower/abdomenUpper/abdomenLower/hip/pelvis/rThighBend/rThighTwist/rShin/rFoot/rMetatarsals/rToe"), "Right Leg", true, new Vector3(0, 0, 0));

        //=== Init CObject ===
        _oObj = new CObject(this, _oBody._oBodyBase._nBodyID, typeof(EActorLeg), "Leg", "Leg" + _sSidePrefixU);
        _oObj.PropGroupBegin("", "", true);
        AddBaseActorProperties();						// The first properties of every CActor subclass are Pinned, pos & rot
        _oObj.PropAdd(EActorLeg.Thigh_Spread,	"Thigh-Spread",		0,	-100,	100,	"");
        _oObj.PropAdd(EActorLeg.Thigh_Rotate,	"Thigh-Rotate",		0,	-100,	100,	"");
        _oObj.FinishInitialization();

        //_oKeyHook_ThighSpread = new CKeyHook(_oObj.PropFind(EActorLeg.Thigh_Spread), KeyCode.F, EKeyHookType.QuickMouseEdit, "Thigh Spread", -1);
    }
Ejemplo n.º 2
0
    //---------------------------------------------------------------------------	CREATE / DESTROY
    public override void OnStart_DefineLimb()
    {
        //=== Init Bones and Joints ===
        _aJoints.Add(_oJointExtremity	    = CJointDriver.Create(this, null,					"chestUpper",		15,  8, -000,  000,  000,  000, 1));		//### The body's root bone... is kinematic and has no joint to a parent bone so all zeros
        _aJoints.Add(_oJointChestLower      = CJointDriver.Create(this, _oJointExtremity,		"chestLower",		15,  8, -015,  015,  010,  010, 1));
        _aJoints.Add(_oJointAbdomenUpper	= CJointDriver.Create(this, _oJointChestLower,      "abdomenUpper",	    15,  6, -035,  025,  012,  020, 1));
        _aJoints.Add(_oJointAbdomenLower    = CJointDriver.Create(this, _oJointAbdomenUpper,    "abdomenLower",	    15,  6, -040,  025,  024,  020, 1));
        _aJoints.Add(_oJointHip			    = CJointDriver.Create(this, _oJointAbdomenLower,	"hip",			    15,  6, -035,  020,  015,  015, 1));
        //###NOTE: Pelvis bone is in CActorPelvis for extra processing there.

        //###CHECK: Keep? _oJointExtremity._oRigidBody.isKinematic = (CGame.INSTANCE._GameMode == EGameModes.Configure);		//###HACK ###TEMP ####REVA If play no anim just set everything to kinematic... for temp cloth exploration
        //###OBS? _oJointExtremity._oRigidBody.isKinematic = false;				// We need to disable kinematic on bone as we're driving it with our pin!

        //=== Init Hotspot ===
        _oHotSpot = CHotSpot.CreateHotspot(this, transform, "Chest", true, new Vector3(0, 0, 0), C_SizeHotSpot_BodyNodes);
        //_oHotSpot = CHotSpot.CreateHotspot(this, _oBody.FindBone("chestUpper"), "Chest", true, new Vector3(0, 0, 0), C_SizeHotSpot_TorsoNodes);

        //=== Init CObject ===
        _oObj = new CObject(this, _oBody._oBodyBase._nBodyID, typeof(EActorChest), "Chest", "Chest");
        _oObj.PropGroupBegin("", "", true);
        AddBaseActorProperties();						// The first properties of every CActor subclass are Pinned, pos & rot
        _oObj.PropAdd(EActorChest.Torso_LeftRight,	"Torso_LeftRight",	0,	-100,	100,	"");		//###BUG: Have to recalibrate to make new abdoment-centric bones look good.
        _oObj.PropAdd(EActorChest.Torso_UpDown,		"Torso_UpDown",		0,	-100,	100,	"");		//###NOW###: Forced to enter crappy name because of new CProp restrictions with naming!
        _oObj.PropAdd(EActorChest.Torso_Twist,		"Torso_Twist",		0,	-100,	100,	"");
        _oObj.FinishInitialization();
        //###PROBLEM: Base actor adds 'pinned' but chest is always pinned?

        //###CHECK??
        _oObj.PropSet(EActorChest.Pinned, 1);           // Manually set pinned to 1 on torso so body doesn't float in space when no pose is loaded (Weak that we can't set in PropAdd() due to init-time problems)

        if (CGame.INSTANCE.EnableIdlePoseMovement)
            StartCoroutine(Coroutine_ChangeRandomPose());			//###CHECK: When destroyed OK??
    }
Ejemplo n.º 3
0
    public void OnStart()
    {
        _oHotSpot = CHotSpot.CreateHotspot(this, transform, "Pose Root", true, Vector3.zero, 2.0f);

        _oObj = new CObject(this, 0, typeof(EPoseRoot), "Pose Root");
        _oObj.PropGroupBegin("", "", true);
        //###BROKEN: Need to flip load order, not 180!!  _oObj.PropAdd(EPoseRoot.Flipped,	"Flip Pose",		0,	"", CProp.Local | CProp.AsCheckbox);	//###IMPROVE: Add a separation member with key hook.  A height too??
        _oObj.FinishInitialization();
    }
Ejemplo n.º 4
0
    // CActorNode: Simple 'node based' actor without joints to enable user to move / rotate other real actors... Currently used for base and torso
    //###DESIGN: Really keep design based on CActor???  Just needs to move a simple node!
    public override void OnStart_DefineLimb()
    {
        //=== Init Bones and Joints ===
        _oHotSpot = CHotSpot.CreateHotspot(this, transform, transform.name, true, Vector3.zero, C_SizeHotSpot_BodyNodes);		//###DESIGN!!!!: How can user move actors apart that get too close??

        //=== Init CObject ===
        _oObj = new CObject(this, _oBody._oBodyBase._nBodyID, typeof(EActorNode), transform.name, transform.name);	//###DESIGN: Keep???
        _oObj.PropGroupBegin("", "", true);
        AddBaseActorProperties();						// The first properties of every CActor subclass are Pinned, pos & rot
        //###DESIGN? _oObj.PropAdd(EActorNode.Height,	"Height",		0.5f,	0.5f,	1.2f,	"", CProp.Local);		//###DESIGN: Range tuned to standing height
        _oObj.FinishInitialization();
    }
Ejemplo n.º 5
0
    public CBody(CBodyBase oBodyBase)
    {
        //###NOW#11
        _oBodyBase = oBodyBase;
        _oBodyBase._oBody = this;           //###WEAK#13: Convenience early-set of our instance into owning parent.  Needed as some of init code needs to access us from our parent! ###DESIGN!
        _oBodySkinnedMeshGO_HACK = new GameObject("RuntimeBody");       // Create the game object that will contain our important CBody component early (complex init tree needs it!)
        _oBodySkinnedMeshGO_HACK.transform.SetParent(_oBodyBase._oBodyRootGO.transform);
        _bEnabled = true;			// Enabled at creation by defnition.

        //bool bForMorphingOnly = false;  //###JUNK (CGame.INSTANCE._GameMode == EGameModes.MorphNew_TEMP);				//####DEV!!!!
        Debug.Log(string.Format("+ Creating body #{0}", _oBodyBase._nBodyID));

        _oObj = new CObject(this, _oBodyBase._nBodyID, typeof(EBodyDef), "Body");
        _oObj.PropGroupBegin("", "", true);
        //_oObj.PropAdd(EBodyDef.Sex,				"Sex",				typeof(EBodySex), (int)EBodySex.Woman,	"");
        //_oObj.PropAdd(EBodyDef.ClothingTop,		"Top Clothing",		typeof(EBodyClothingTop_HACK), 0, "");		//###HACK!!!!
        //_oObj.PropAdd(EBodyDef.ClothingBottom,	"Bottom Clothing",	typeof(EBodyClothingBottom_HACK), 0, "" + CProp.Hide);	//###BROKEN: Need to switch off v****a soft body!!
        //_oObj.PropAdd(EBodyDef.Hair,			"Hair",				typeof(EBodyHair), 0,	"");
        //_oObj.PropAdd(EBodyDef.BtnUpdateBody,	"Update Body",		0,	"", CProp.AsButton);
        _oObj.PropAdd(EBodyDef.BreastSize,		"Breast Size BROKEN",		1.0f, 0.5f, 2.5f, "");		//###BROKEN#11
        _oObj.FinishInitialization();

        //=== Give some reasonable defaults to use when game loads ===		###TODO: Load these from the user's last used body definitions!		####TEMP ####DESIGN: Load from user pref or file?  NOT IN CODE!!
        //		if (_oBodyBase._nBodyID == 0) {
        //			_oObj.PropSet(EBodyDef.Sex,				(int)EBodySex.Woman);
        //			//_oObj.PropSet(EBodyDef.Sex,				(int)EBodySex.Shemale);
        //			_oObj.PropSet(EBodyDef.Hair, (int)EBodyHair.TiedUp);
        ////			oObj.PropSet(EBodyDef.Hair, (int)EBodyHair.Messy);
        ////			oObj.PropFind(EBodyDef.ClothingTop)._nPropFlags |= CProp.Hide;		//###HACK!!!!
        ////			oObj.PropFind(EBodyDef.BreastSize)._nPropFlags |= -CProp.Hide;
        ////			oObj.PropFind(EBodyDef.Hair)._nPropFlags |= CProp.Hide;
        //		} else {
        //			//_oObj.PropSet(EBodyDef.Sex,				(int)EBodySex.Man);		####REVB
        //			_oObj.PropSet(EBodyDef.Sex,				(int)EBodySex.Shemale);
        //			//oObj.PropSet(EBodyDef.ClothingTop, (int)EBodyClothingTop_HACK.TiedTop);
        //			_oObj.PropSet(EBodyDef.Hair, (int)EBodyHair.TiedUp);
        //			//if (CGame.INSTANCE._bRunningInEditor)		//###TEMP! :)
        //			//	oObj.PropSet(EBodyDef.BreastSize, 1.3f);
        //		}

        //===== DETACHED SOFTBODY PARTS PROCESSING =====
        if (_oBodyBase._eBodySex != EBodySex.Man) {
            //_aSoftBodies.Add(_oBreastL = (CBreastL)CSoftBody.Create(this, typeof(CBreastL), "chestUpper"));        //###DEVNOW
            //_aSoftBodies.Add(_oBreastR = (CBreastR)CSoftBody.Create(this, typeof(CBreastR), "chestUpper"));
        }
        if (_oBodyBase._eBodySex == EBodySex.Woman) {
            //_aSoftBodies.Add(_oVagina = (CVagina)CSoftBody.Create(this, typeof(CVagina), "chest/abdomen/hip"));
        } else {
            //_aSoftBodies.Add(_oPenis = (CPenis)CSoftBody.Create(this, typeof(CPenis), "chest/abdomen/hip"));
        }

        ////####TEMP ####DESIGN ####TEMP ####MOVE
        //_aCloths.Add(CBCloth.Create(this, "MyShirt", "Shirt", "HACK-Cloth-TankTop", "_ClothSkinnedArea_ShoulderTop"));    //_ClothSkinnedArea_Top
        ///_aCloths.Add(CBCloth.Create(this, "MyShirt", "Shirt", "BodySuit", "_ClothSkinnedArea_ShoulderTop"));    //_ClothSkinnedArea_Top
        ////_aCloths.Add(CBCloth.Create(this, "Rough1-Holds"));
        ////_aCloths.Add(CBCloth.Create(this, "Rough2-Spreads"));
        ////_aCloths.Add(CBCloth.Create(this, "BodySuit-Top-Trimmed"));
        ////////////###DEV _aCloths.Add(CBCloth.Create(this, "FullShirt"));

        ////=== Create the various soft-body mesh parts that are dependant on the body sex ===
        ////###IMPROVE!!!! Parse array of Blender-pushed softbody into our parts (instead of pulling like below?)
        //if (_bForMorphingOnly == false) {
        //	if (_eBodySex == EBodySex.Woman || _eBodySex == EBodySex.Shemale) {
        //		_aSoftBodies.Add(_oBreastL = (CBreastBase)CBMesh.Create(null, this, _sNameGameBody, "_Detach_Breasts", "Client", "Unity_GetMesh", "'SkinInfo'", typeof(CBreastBase)));           //###WEAK: Create utility function like before???
        //	}
        //	if (_eBodySex == EBodySex.Shemale || _eBodySex == EBodySex.Man)
        //		_aSoftBodies.Add(_oPenis = (CPenis)CBMesh.Create(null, this, _sNameGameBody, "_Detach_Penis", "Client", "Unity_GetMesh", "'NoSkinInfo'", typeof(CPenis)));
        //	if (_eBodySex == EBodySex.Woman)
        //		_oVagina = new CVagina(this);

        //	//=== Create the important body collider that will repel fluid in the scene ===
        //	_oBodyCol = (CBBodyCol)CBBodyCol.Create(null, this, _sNameGameBody);
        //}

        //=== Obtain the source mesh body for normal extraction ===
        ///_oBodySource = CBMesh.Create(null, this, "oMeshSource", typeof(CBMesh));
        ///_oBodySource.GetComponent<MeshRenderer>().enabled = false;					// This mesh is to pull normals only.  Not visible at runtime!

        //===== MAIN SKINNED BODY PROCESSING =====
        //=== Get the main body skinned mesh (has to be done once all softbody parts have been detached) ===
        _oBodySkinnedMesh = (CBSkin)CBMesh.Create(_oBodySkinnedMeshGO_HACK, _oBodyBase, ".oBody.oMeshBody", typeof(CBSkin)); //###IMPROVE#13: Create blender instance string for our CBody?
        _oBodySkinnedMesh.name = "GametimeBody";
        //_oBodySkinnedMesh.GetComponent<SkinnedMeshRenderer>().enabled = false;

        //=== Create a hotspot at the character's head the user can use to invoke our (important) context menu ===
        //###BROKENN
        //      Transform oHeadT = FindBone("chest/neck/head");         // Our hotspot is located on the forehead of the character.
        //_oHotSpot = CHotSpot.CreateHotspot(this, oHeadT, this._sHumanCharacterName, false, new Vector3(0, 0.09f, 0.03f), 2.0f);     //###IMPROVE: Get these offsets from pre-placed nodes on bone structure??

        ////=== Create the head look controller to look at parts of the other body ===
        //###BROKENN
        //      _oHeadLook = _oBodyRootGO.gameObject.AddComponent<CHeadLook>();			//####DESIGN: Keep for morph mode??
        //_oHeadLook.OnStart(this);

        //=== Instantiate the requested hair and pin as child of the head bone ===
        //###BROKENN
        //EBodyHair eBodyHair = (EBodyHair)_oObj.PropGet(EBodyDef.Hair);
        //if (eBodyHair != EBodyHair.None) {
        //	string sNameHair = "HairW-" + eBodyHair.ToString();         //###HACK!!! W extension!		###HACK!!!! Man support!!
        //	GameObject oHairTemplateGO = Resources.Load("Models/Characters/Woman/Hair/" + sNameHair + "/" + sNameHair, typeof(GameObject)) as GameObject;   // Hair has name of folder and filename the same.	//###HACK: Path to hair, selection control, enumeration, etc
        //	_oHairGO = GameObject.Instantiate(oHairTemplateGO) as GameObject;
        //	Transform oBoneHead = FindBone("chest/neck/head");
        //	_oHairGO.transform.parent = oBoneHead;
        //	_oHairGO.transform.localPosition = Vector3.zero;
        //	_oHairGO.transform.localRotation = Quaternion.identity;
        //	if (_eBodySex == EBodySex.Man) {            //###HACK!!!!!! To reuse messy hair for man!!
        //		_oHairGO.transform.localPosition = new Vector3(0, 0.0f, 0.0f);
        //		_oHairGO.transform.localScale = new Vector3(1.07f, 1.07f, 1.08f);
        //	}
        //}

        Body_InitActors();

        ////=== Setup the keys to handle penis control on non-woman bodies ===
        //if (_eBodySex != EBodySex.Woman) {      //###MOVE?        ###OBS ###F
        //	bool bSelectedBodyOnly = (CGame.INSTANCE._nNumPenisInScene_BROKEN > 1);    // Keys below are active if this body is the selected body ONLY if we have more than one man in the scene
        //	if (_oPenis != null) {
        //		_oKeyHook_PenisBaseUpDown = new CKeyHook(_oPenis._oObjDriver.PropFind(EPenis.BaseUpDown), KeyCode.Q, EKeyHookType.QuickMouseEdit, "Penis up/down", 1, bSelectedBodyOnly);
        //		_oKeyHook_PenisShaftUpDown = new CKeyHook(_oPenis._oObjDriver.PropFind(EPenis.ShaftUpDown), KeyCode.E, EKeyHookType.QuickMouseEdit, "Penis bend up/down", 1, bSelectedBodyOnly);
        //		_oKeyHook_PenisDriveStrengthMax = new CKeyHook(_oPenis._oObjDriver.PropFind(EPenis.DriveStrengthMax), KeyCode.G, EKeyHookType.QuickMouseEdit, "Penis erection", -1, bSelectedBodyOnly);
        //	}
        //}
        _oKeyHook_ChestUpDown = new CKeyHook(_oActor_Chest._oObj.PropFind(EActorChest.Torso_UpDown), KeyCode.T, EKeyHookType.QuickMouseEdit, "Chest forward/back");

        //=== Create the face and its associated morph channels ===
        ///_oFace = (CFace)CBMesh.Create(null, this, "oMeshFace", typeof(CFace));

        //=== Reparent our actor base to the pose root so that user can move / rotate all bodies at once ===
        _oActor_Base.transform.SetParent(CGame.INSTANCE._oPoseRoot.transform);		//###DESIGN#15! Causes problems with regular init/destory of CBody?  Do we really want to keep reparenting for easy full pose movement??>
        _oActor_Base.gameObject.name = _oBodyBase._sBodyPrefix + "_Base";

        //=== Copy references to our actors to our script-friendly CObject variables to provide friendlier access to our scriptable objects ===
        Base    = _oActor_Base._oObj;              // CGamePlay passed us the reference to the right (empty) static object.  We fill it here.
        Chest   = _oActor_Chest._oObj;
        Torso   = _oActor_Torso._oObj;
        Pelvis  = _oActor_Pelvis._oObj;
        ArmL    = _oActor_ArmL._oObj;
        ArmR    = _oActor_ArmR._oObj;
        LegL    = _oActor_LegL._oObj;
        LegR    = _oActor_LegR._oObj;
        Face = null;/// _oFace._oObj;
        ///###BROKEN ###DEVO Penis = (_oPenis == null) ? null : _oPenis._oObjDriver;

        _oScriptPlay = CUtility.FindOrCreateComponent(_oBodyBase._oBodyRootGO.transform, typeof(CScriptPlay)) as CScriptPlay;
        _oScriptPlay.OnStart(this);

        //=== Rotate the 2nd body toward the first and separate slightly loading poses doesn't pile up one on another ===	####MOVE? ####OBS? (Depend on pose?)
        //####PROBLEM: Set separation and don't do in all game modes
        if (_oBodyBase._nBodyID == 0) {
            _oActor_Base.transform.position = new Vector3(0, 0, -CGame.C_BodySeparationAtStart);        //###DESIGN: Don't load base actor instead??  ###BUG Overwrites user setting of base!!!!
        } else {
            _oActor_Base.transform.position = new Vector3(0, 0, CGame.C_BodySeparationAtStart);
            _oActor_Base.transform.rotation = Quaternion.Euler(0, 180, 0);      // Rotate the 2nd body 180 degrees
        }

        ///_oClothEdit_HACK = new CClothEdit(this, "Shirt");

        ///CGame.gBL_SendCmd("CBody", "CBodyBase_GetBodyBase(" + _oBodyBase._nBodyID.ToString() + ").Breasts_ApplyMorph('RESIZE', 'Nipple', 'Center', 'Wide', (1.6, 1.6, 1.6, 0), None)");       //###F ###HACK!!!

        //=== Create the left and right canvases on each side of the body so that panels have a place to be pinned for close-to-body editing ===
        _aUICanvas[0] = CUICanvas.Create(CUtility.FindChild(_oActor_Chest.transform, "_CanvasPin_Left"));        //###HACK
        _aUICanvas[1] = CUICanvas.Create(CUtility.FindChild(_oActor_Chest.transform, "_CanvasPin_Right"));        //###DESIGN: Which pin?  Torso or chest?

        //=== Create the Flex collider in Blender and serialize it to Unity ===
        CGame.gBL_SendCmd("CBody", _oBodyBase._sBlenderInstancePath_CBodyBase + ".oBody.CreateFlexCollider(" + CGame.INSTANCE.nDistFlexColliderShrinkMult + ")");
        _oBodyFlexCollider = (CBSkin)CBMesh.Create(null, _oBodyBase, ".oBody.oMeshFlexCollider", typeof(CBSkin));
        _oBodyFlexCollider.name = "FlexCollider";
        _oBodyFlexCollider.transform.SetParent(_oBodySkinnedMesh.transform);		//###IMPROVE#15: Put this common re-parenting and re-naming in Create!
        _oBodyFlexCollider.gameObject.AddComponent<CFlexSkinnedBody>();
        _oBodyFlexCollider.GetComponent<SkinnedMeshRenderer>().enabled = false;     //###IMPROVE: Move into CFlexSkinnedBody??
        _oBodyFlexCollider.UpdateNormals();			//###NOW#15
    }
Ejemplo n.º 6
0
    //---------------------------------------------------------------------------	CREATE / DESTROY
    public override void OnStart_DefineLimb()
    {
        //###CHECK _aJoints.Add(_oJointExtremity = CJointDriver.Create(this, _oBody._oActor_Chest._oJointHip, "sex", 1.0f, 1.0f, -0f, 0, -0f, 0f, -0f, 0f));
        _aJoints.Add(_oJointExtremity = CJointDriver.Create(this, _oBody._oActor_Chest._oJointHip,	"pelvis", 15, 8, -025,  025,  010,  015, 1));

        _oHotSpot = CHotSpot.CreateHotspot(this, transform, "Pelvis", true, new Vector3(0, 0, 0), C_SizeHotSpot_BodyNodes);

        _oObj = new CObject(this, _oBody._oBodyBase._nBodyID, typeof(EActorPelvis), "Pelvis", "Pelvis");
        _oObj.PropGroupBegin("", "", true);
        AddBaseActorProperties();						// The first properties of every CActor subclass are Pinned, pos & rot
        _oObj.FinishInitialization();
        _oObj.PropSet(EActorPelvis.Pinned, 1);			// Manually set pinned to 1 on chest so body doesn't float in space when no pose is loaded (Weak that we can't set in PropAdd() due to init-time problems)
    }
Ejemplo n.º 7
0
    public override void OnDeserializeFromBlender()
    {
        base.OnDeserializeFromBlender();

        _sBlenderInstancePath_CCloth = CBCloth.s_sNameClothSrc_HACK;

        //=== Create the skinned-portion of the cloth.  It will be responsible for driving Flex particles that heavily influence their corresponding particles in fully-simulated cloth mesh ===
        _oBSkinBaked_SkinnedPortion = (CBSkinBaked)CBSkinBaked.Create(null, _oBodyBase, "." + _sBlenderInstancePath_CCloth + ".oMeshClothSkinned", typeof(CBSkinBaked));    //###WEAK#13!!! F*****g dot!!
        _oBSkinBaked_SkinnedPortion.transform.SetParent(transform);
        _oBSkinBaked_SkinnedPortion._oSkinMeshRendNow.enabled = false;          // Skinned portion invisible to the user.  Only used to guide simulated portion

        //=== Receive the aMapPinnedParticles array Blender created to map the skinned verts to their pertinent simulated ones ===
        List<ushort> aMapPinnedParticles = CByteArray.GetArray_USHORT("'CBody'", _oBodyBase._sBlenderInstancePath_CBodyBase + "." + _sBlenderInstancePath_CCloth + ".aMapPinnedParticles.Unity_GetBytes()");

        //=== Create the simulated part of the cloth ===
        MeshFilter oMeshFilter = GetComponent<MeshFilter>();
        MeshRenderer oMeshRend = GetComponent<MeshRenderer>();
        //oMeshRend.sharedMaterial = Resources.Load("Materials/BasicColors/TransWhite25") as Material;        //####SOON? Get mats!  ###F
        oMeshRend.sharedMaterial = Resources.Load("Materials/Test-2Sided") as Material;        //####SOON? Get mats!  ###F
        _oBSkinBaked_SkinnedPortion._oSkinMeshRendNow.sharedMaterial = oMeshRend.sharedMaterial;        // Skinned part has same material
        _oMeshNow = oMeshFilter.sharedMesh;
        _oMeshNow.MarkDynamic();                // Docs say "Call this before assigning vertices to get better performance when continually updating mesh"

        //=== Create the 'cloth at startup' mesh.  It won't get simulated and is used to reset simulated cloth to its startup position ===
        _oBMeshClothAtStartup = CBMesh.Create(null, _oBodyBase, "." + _sBlenderInstancePath_CCloth + ".oMeshClothSimulated", typeof(CBMesh));
        _oBMeshClothAtStartup.transform.SetParent(_oBodyBase.FindBone("chestUpper"));      // Reparent this 'backup' mesh to the chest bone so it rotates and moves with the body
        _oBMeshClothAtStartup.GetComponent<MeshRenderer>().enabled = false;
        //_oBMeshClothAtStartup.gameObject.SetActive(false);      // De activate it so it takes no cycle.  It merely exists for backup purposes

        //=== Create the Flex object for our simulated part ===
        CFlex.CreateFlexObject(gameObject, _oMeshNow, _oMeshNow, uFlex.FlexBodyType.Cloth, uFlex.FlexInteractionType.None, CGame.INSTANCE.nMassCloth, Color.yellow);
        uFlex.FlexProcessor oFlexProc = CUtility.FindOrCreateComponent(gameObject, typeof(uFlex.FlexProcessor)) as uFlex.FlexProcessor;
        oFlexProc._oFlexProcessor = this;
        _oFlexParticles = GetComponent<uFlex.FlexParticles>();
        _oFlexSprings   = GetComponent<uFlex.FlexSprings>();

        //=== Create the managing object and related hotspot ===
        _oObj = new CObject(this, 0, typeof(EFlexCloth), "Cloth " + gameObject.name);        //###IMPROVE: Name of soft body to GUI
        _oObj.PropGroupBegin("", "", true);
        _oObj.PropAdd(EFlexCloth.Tightness,     "Tightness",    1.0f, 0.01f, 2.5f, "");
        _oObj.PropAdd(EFlexCloth.Length,        "Length",       1.0f, 0.50f, 1.10f, "");
        _oObj.PropAdd(EFlexCloth.ClothMass,     "Mass",         1.0f, 0.0001f, 1000.0f, "");
        _oObj.FinishInitialization();
        _oWatchBone = _oBodyBase.FindBone("chestUpper");            //####HACK ####DESIGN: Assumes this cloth is a top!
        _oHotSpot = CHotSpot.CreateHotspot(this, _oWatchBone, "Clothing", false, new Vector3(0, 0.22f, 0.04f));     //###IMPROVE!!! Position offset that makes sense for that piece of clothing (from center of its verts?)

        //=== Backup the startup cloth arrays so we can adjust in a non-destructive way ===
        _aSpringRestLengthsBAK = new float[_oFlexSprings.m_springsCount];
        System.Array.Copy(_oFlexSprings.m_springRestLengths, _aSpringRestLengthsBAK, _oFlexSprings.m_springsCount);

        //=== Create the Flex-to-skinned-mesh component responsible to guide selected Flex particles to skinned-mesh positions ===
        _oPinnedParticles = CUtility.FindOrCreateComponent(gameObject, typeof(CPinnedParticles)) as CPinnedParticles;
        _oPinnedParticles.Initialize(ref aMapPinnedParticles, _oBSkinBaked_SkinnedPortion);
    }
Ejemplo n.º 8
0
    //---------------------------------------------------------------------------	CREATE / DESTROY
    public override void OnStart_DefineLimb()
    {
        _nDrivePos = 0.1f * C_DrivePos;				// Weaken the hand drive so hand doesn't fly from pin to pin		//###TUNE
        //_memVecRayHitInfo = new CMemAlloc<Vector3>(2);

        //=== Init Bones and Joints ===
        CJointDriver oJointChestUpper = _oBody._oActor_Chest._oJointExtremity;
        _aJoints.Add(_oJointCollar	        = CJointDriver.Create(this, oJointChestUpper,	    _sSidePrefixL+"Collar",	        30, 2.5f, -010,  050,  030,  021, 1));		// X = Collar Up/Down OK, Z has 17 back and 25 forward (avg looks ok)
        _aJoints.Add(_oJointShoulderBend    = CJointDriver.Create(this, _oJointCollar,		    _sSidePrefixL+"ShldrBend",	    15, 2.0f, -085,  035,  000,  110, 1));		// X = Shoulder Up/Down OK, Z = Back goes to -40, Forward to 110!!!  (###IMPROVE: Another joint?)
        _aJoints.Add(_oJointShoulderTwist   = CJointDriver.Create(this, _oJointShoulderBend,    _sSidePrefixL+"ShldrTwist",	    20, 1.5f, -000,  000,  080,  000, 1));		// Y = Shoulder twist goes from -95 to 80 so max.  ###PROBLEM: Shimmer in high rotation!
        _aJoints.Add(_oJointForearmBend	    = CJointDriver.Create(this, _oJointShoulderTwist,	_sSidePrefixL+"ForearmBend",	10, 1.5f, -020,  135,  000,  000, 1));		// X = Elbow bend from -20 to 135. ok.
        _aJoints.Add(_oJointForearmTwist    = CJointDriver.Create(this, _oJointForearmBend,	    _sSidePrefixL+"ForearmTwist",	20, 1.0f, -000,  000,  080,  000, 1));		// Y = Forearm twist from -90 to 80 so max.		###IMPROVE: Could rotate the axes on the twists so we use XL/XH
        _aJoints.Add(_oJointExtremity       = CJointDriver.Create(this, _oJointForearmTwist,	_sSidePrefixL+"Hand",			10, 0.5f, -070,  080,  010,  029, 1));		// X = Hand -down(-70) / +up (+80), Y = Hand twist +/-10, Z = Hand side-to-side -28 to +30

        //ConfigFingerRoot(1, "Index");			// Thumb is handled below		###DESIGN!!! Fingers in Unity PhysX is just a no-go because of extremely poor latency... what to do?????
        //ConfigFingerRoot(2, "Mid");
        //ConfigFingerRoot(3, "Ring");			//??? ###HACK!! Disabled man's carpal1&2 in 3dsMax so we can use same code as women's!
        //ConfigFingerRoot(4, "Pinky");

        //CJointDriver oJointFingerBoneParent = _oJointExtremity;
        //oJointFingerBoneParent = ConfigFingerBone(oJointFingerBoneParent, 0, 0, "Thumb", 005f, -030f,  005f,  025f);
        //oJointFingerBoneParent = ConfigFingerBone(oJointFingerBoneParent, 0, 1, "Thumb", 010f, -015f,  000f,  000f);
        //oJointFingerBoneParent = ConfigFingerBone(oJointFingerBoneParent, 0, 2, "Thumb", 010f, -015f,  000f,  000f);

        //=== Init Hotspot ===
        if (_eBodySide == 0)
            _oHotSpot = CHotSpot.CreateHotspot(this, _oBody._oBodyBase.FindBone("chestUpper/lCollar/lShldrBend/lShldrTwist/lForearmBend/lForearmTwist/lHand"), "Left Hand", true, new Vector3(0, 0, 0));
        else
            _oHotSpot = CHotSpot.CreateHotspot(this, _oBody._oBodyBase.FindBone("chestUpper/rCollar/rShldrBend/rShldrTwist/rForearmBend/rForearmTwist/rHand"), "Right Hand", true, new Vector3(0, 0, 0));

        //=== Init CObject ===
        _oObj = new CObject(this, _oBody._oBodyBase._nBodyID, typeof(EActorArm), "Arm", "Arm" + _sSidePrefixU);
        _oObj.PropGroupBegin("", "", true);
        AddBaseActorProperties();						// The first properties of every CActor subclass are Pinned, pos & rot
        //_oObj.PropAdd(EActorArm.HandTarget,			"HandTarget",			typeof(EHandTargets), (int)EHandTargets.ManualPosition, "");
        _oObj.PropAdd(EActorArm.Hand_UpDown,		"Hand-UpDown",			0,	-100,	100, "");
        _oObj.PropAdd(EActorArm.Hand_LeftRight,		"Hand-LeftRight",		0,	-100,	100, "");
        _oObj.PropAdd(EActorArm.Hand_Twist,			"Hand-Twist",			0,	-100,	100, "");
        //_oObj.PropAdd(EActorArm.Fingers_Close,		"Fingers-Close",		0,	-100,	100, "", CProp.Hide);		//###BROKEN
        //_oObj.PropAdd(EActorArm.Fingers_Spread,		"Fingers-Spread",		0,	-100,	100, "", CProp.Hide);
        //_oObj.PropAdd(EActorArm.Fingers_ThumbPose,	"Fingers-ThumbPose",	typeof(EThumbPose), (int)EThumbPose.AlongsideFingers, "", CProp.Hide);
        //_oObj.PropAdd(EActorArm.UserControl,		"User Control",			0,		0,		1, "");
        _oObj.FinishInitialization();

        _oHandTarget_RaycastPin = CActorArm.FindHandTarget(_oBody, EHandTargets.RaycastPin, _eBodySide == EBodySide.Right);	// Find the raycast pin hand target as we use it heavily and it is reparented
    }
Ejemplo n.º 9
0
    //---------------------------------------------------------------------------	INIT
    public override void OnDeserializeFromBlender()
    {
        base.OnDeserializeFromBlender();
        transform.SetParent(_oBodyBase._oBody._oBodySkinnedMeshGO_HACK.transform);			// Parent to our body's main skinned mesh	###WEAK#14: Crappy circumvent way of obtaining node we need early in init!

        _sNameSoftBody = GetType().Name.Substring(1);                            // Obtain the name of our detached body part ('Breasts', 'Penis', 'V****a') from a substring of our class name.  Must match Blender!!  ###WEAK?
        _sBlenderInstancePath_CSoftBody = ".oBody.aSoftBodies['" + _sNameSoftBody + "']";                          // Simplify access to Blender CSoftBody instance
        _sBlenderInstancePath_CSoftBody_FullyQualfied = _oBodyBase._sBlenderInstancePath_CBodyBase + _sBlenderInstancePath_CSoftBody; // Simplify access to fully-qualified Blender CSoftBody instance (from CBody instance)
        _oBoneAnchor = _oBodyBase._oBody._oBodyBase.FindBone(_sNameBoneAnchor_HACK);

        //=== Set bounds to infinite so our dynamically-created mesh never has to recalculate bounds ===
        _oMeshNow.bounds = CGame._oBoundsInfinite;          //####IMPROVE: This can hurt performance ####OPT!!
        _oMeshNow.MarkDynamic();        // Docs say "Call this before assigning vertices to get better performance when continually updating mesh"

        //=== Create the managing object and related hotspot ===
        _oObj = new CObject(this, 0, typeof(EFlexSoftBody), "SoftBody " + gameObject.name);        //###IMPROVE: Name of soft body to GUI
        _oObj.PropGroupBegin("", "", true);
        _oObj.PropAdd(EFlexSoftBody.Volume,         "Volume",       1.0f, 0.6f, 1.6f, "");
        _oObj.PropAdd(EFlexSoftBody.Stiffness,      "Stiffness",    1.0f, 0.001f, 1.0f, "");       //###IMPROVE: Log scale!
        _oObj.PropAdd(EFlexSoftBody.SoftBodyMass,   "Mass",         1.0f, 0.0001f, 1000.0f, "");
        _oObj.FinishInitialization();
        if (GetType() != typeof(CBreastR))          //###HACK!: Right breast doesn't get hotspot (left breast gets it and manually broadcasts to right one)
            _oHotSpot = CHotSpot.CreateHotspot(this, _oBoneAnchor, "SoftBody", false, new Vector3(0, 0.10f, 0.08f));     //###IMPROVE!!! Position offset that makes sense for that piece of clothing (from center of its verts?)
    }
Ejemplo n.º 10
0
    public void Start()
    {
        //    StartCoroutine(Coroutine_StartGame());			// Handled by a coroutine so that our 'OnGui' can run to update the 'Please wait' dialog
        //}
        //public IEnumerator Coroutine_StartGame() {		//####OBS: IEnumerator?? //###NOTE: Game is started by iGUICode_Root once it has completely initialized (so as to present the 'Please Wait...' dialog

        Debug.Log("=== CGame.StartGame() ===");
        INSTANCE = this;
        _nTimeAtStart = Time.time;

        //GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CSoftBody));     //###NOW###
        ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CSoftBodyBase));     //###NOW###
        ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CB));     //###NOW###
        ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CFuckOff));
        ////GameObject oGO_HACK = new GameObject("oGO_HACK", typeof(CJointDriver));
        //return;

        _oFlexSolver = FindObjectOfType<uFlex.FlexSolver>();        //###F
        GameObject oSceneGO = GameObject.Find("SCENE/SceneColliders");
        //if (oSceneGO != null)
        //    s_aColliders_Scene = oSceneGO.GetComponentsInChildren<CCollider_OBS>();

        _bRunningInEditor = true;       //###HACK ####REVA Application.isEditor
        _DemoVersion = (_bRunningInEditor == false);		//###CHECK? If dev has Unity code they are non-demo

        _oCursor = CCursor.Cursor_Create();             //###DESIGN!!!!!: REVISIT!	###CLEANUP!!!!!
        Cursor.visible = Application.isEditor;      // _bRunningInEditor;

        //=== Set rapid-access members to text widgets so we can rapidly update them ===
        _oTextUL = GameObject.Find("/UI/CanvasScreen/UL/Text-UL").GetComponent<Text>();
        _oTextUC = GameObject.Find("/UI/CanvasScreen/UC/Text-UC").GetComponent<Text>();
        _oTextUR = GameObject.Find("/UI/CanvasScreen/UR/Text-UR").GetComponent<Text>();

        //=== Create user-adjustable top-level game options ===
        _oObj = new CObject(this, 0, typeof(EGamePlay), "Erotic9");		//###TEMP!!! Main game name in this low-importance GUI???
        _oObj.PropGroupBegin("", "", true);		//###CLEANUP
        //_oObj.PropAdd(EGamePlay.Pleasure,			"Pleasure",		30,		-100,	100,	"Amount of pleasure experienced by game characters.  Influences 'Arousal' (NOTE: Temporary game mechanism)");	//###BUG with first setting
        //_oObj.PropAdd(EGamePlay.Arousal,			"Arousal",		0,		0,		100,	"Current state of arousal from game characters.  Currently influence penis size.  (NOTE: Temporary game mechanism)");
        //_oObj.PropAdd(EGamePlay.PoseRootPos,		"Pose Root Position",typeof(EPoseRootPos), 0,	"Base location of pose root.  (e.g. on bed, by bedside, etc)");
        //_oObj.PropAdd(EGamePlay.PenisSize,			"Penis Size",	0,		0,		100,	"", CProp.ReadOnly | CProp.Hide);
        //_oObj.PropAdd(EGamePlay.PenisErectionMax,	"Erection",		0,		0,		100,	"", CProp.ReadOnly | CProp.Hide);
        //_oObj.PropAdd(EGamePlay.FluidConfig,		"Fluid Configuration", 0, "Display the properties of the Erotic9 fluid simulator.  (Advanced)", CProp.AsButton);
        _oObj.FinishInitialization();
        _oHotSpot = CHotSpot.CreateHotspot(this, transform, "Game Options", false, new Vector3(0, 0.0f, 0.0f), 1.0f);

        //if (_GameModeAtStartup == EGameModes.None) {
        //    yield break;
        //}

        float nDelayForGuiCatchup = _bRunningInEditor ? 0.2f : 0.01f;		//###HACK? ###TUNE: Adjustable delay to give iGUI time to update 'Game is Loading' message, with some extra time inserted to make Unity editor appear more responsive during game awake time
        ///yield return new WaitForSeconds(nDelayForGuiCatchup);

        //=== Send async call to authentication so it is ready by the time game has initialized ===
        //		WWW oWWW = null;
        //		if (Application.genuine) {		//###CHECK: Has any value against piracy???
        //			if (Application.internetReachability != NetworkReachability.NotReachable) {		//###CHECK!!!
        //				//####BROKEN?! Why store it if we don't use it? string sMachineID = PlayerPrefs.GetString(G.C_PlayerPref_MachineID);
        //				string sMachineID = CGame.GetMachineID();		//###CHECK Can cause problems if switching adaptors frequently?
        //				oWWW = new WWW("http://www.erotic9.net/cgi-bin/CheckUser.py?Action=Authenticate&MachineID=" + sMachineID);
        //			} else {
        //				Debug.LogError("Warning: Could not authenticate because of Internet unreacheability.");
        //			}
        //		} else {
        //			Debug.LogError("Warning: Could not authenticate because of executable image corruption.");
        //		}

        //=== Try to load our dll to extract helpful error message if it fails, then release it ===
        //Debug.Log("INIT: Attempting to load ErosEngine.dll");         //###BROKEN!  WTF No longer works loading 64 bit dll??
        //int hLoadLibResult = LoadLibraryEx("ErosEngine.dll", 0, 2);
        //if (hLoadLibResult > 32)
        //	FreeLibrary(hLoadLibResult);			// Free our dll so Unity can load it its way.  Based on code sample at http://support.microsoft.com/kb/142814
        //else
        //	CUtility.ThrowException("ERROR: Failure to load ErosEngine.dll.  Error code = " + hLoadLibResult);		// App unusable.  Study return code to find out what is wrong.
        //Debug.Log("INIT: Succeeded in loading ErosEngine.dll");

        //####OBS? GameObject oGuiGO = GameObject.Find("iGUI");			//###TODO!!! Update game load status... ###IMPROVE: Async load so OnGUI gets called???  (Big hassle for that!)
        Debug.Log("0. Game Awake"); ///yield return new WaitForSeconds(nDelayForGuiCatchup);
        int n123 = ErosEngine.Utility_Test_Return123_HACK();			// Dummy call just to see if DLL will load with Unity
        if (n123 != 123)
            CUtility.ThrowException("ERROR: Failure to get 123 from ErosEngine.dll call to Utility_Test_Return123_HACK.");
        Debug.Log("INIT: Succeeded in loading ErosEngine.dll");

        //=== Initialize our gBlender direct-memory buffers ===
        Debug.Log("1. Shared Memory Creation.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);
        if (ErosEngine.gBL_Init(CGame.GetFolderPathRuntime()) == false)
            CUtility.ThrowException("ERROR: Could not start gBlender library!  Game unusable.");

        //=== Spawn Blender process ===
        Debug.Log("2. Background Server Start.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);	//###CHECK: Cannot wait long!!
        _hWnd_Unity = (IntPtr)GetActiveWindow();			// Just before we start Blender obtain the HWND of our Unity editor / player window.  We will need this to re-activate our window.  (Starting blender causes it to activate and would require user to alt-tab back to game!!)
        _oProcessBlender = CGame.LaunchProcessBlender("Erotic9.blend");
        if (_oProcessBlender == null)
            CUtility.ThrowException("ERROR: Could not start Blender!  Game unusable.");
        //_nWnd_Blender_HACK = (IntPtr)GetActiveWindow();

        //=== Start Blender (and our gBlender scripts).  Game cannot run without them ===
        Debug.Log("3. Client / Server Handshake.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);
        if (ErosEngine.gBL_HandshakeBlender() == false)
            CUtility.ThrowException("ERROR: Could not handshake with Blender!  Game unusable.");

        SetForegroundWindow(_hWnd_Unity);           // Set our editor / player back into focus (away from just-spawned Blender)

        //=== Set Blender global variables ===
        CGame.gBL_SendCmd("G", "CGlobals.SetFlexParticleSpacing(" + CGame.INSTANCE.particleSpacing.ToString() + ")");         //###TODO: Add others?

        //=== Start PhysX ===
          //      Debug.Log("4. PhysX3 Init.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);
        //ErosEngine.PhysX3_Create();						// *Must* occur before any call to physics library...  So make sure this object is listed with high priority in Unity's "Script Execution Order"

        //Debug.Log("5. PhysX2 Init.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);
        //ErosEngine.PhysX2_Create();						//###IMPROVE!!! Return argument ###NOTROBUST

        //Debug.Log("6. OpenCL Init.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);
        //		if (System.Environment.CommandLine.Contains("-DisableOpenCL") == false)	//###TODO More / better command line processing?		//###SOON ####BROKEN!!!!! OpenCL breaks cloth GPU!
        //			ErosEngine.MCube_Init();		//###IMPROVE: Log message to user!

        SetForegroundWindow(_hWnd_Unity);			//###WEAK: Can get rid of??

        //=== Start misc stuff ===
        Debug.Log("7. CGame globals.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);
        _oSceneMeshesGO = GameObject.Find("SceneMeshes");			// Remember our scene game object so we can hide/show

        _aGuiMessages = new string[(int)EGameGuiMsg.COUNT];
        _ShowFPS = _ShowSysInfo = _bRunningInEditor;

        //###IMPROVE: Disabled until we need to save CPU cycles...  Create upon user demand to record script!
        //_oScriptRecordUserActions = new CScriptRecord(GetPathScript("RecordedScript"), "Automatically-generated Erotic9 Scene Interation Script");

        _oPoseRoot = GameObject.Find("CPoseRoot").GetComponent<CPoseRoot>();
        _oPoseRoot.OnStart();

        //_oFluid = gameObject.AddComponent<CFluid>();
        //_oFluid.OnAwake();

        Application.targetFrameRate = _TargetFrameRate;			//###BUG!!! Why no effect????
        _DefaultJointSpringOld = _DefaultJointSpring;		//###OBS
        _DefaultJointDampingOld = _DefaultJointDamping;

        _oCamTarget = GameObject.Find("CCamTarget").GetComponent<CCamTarget>();		//###WEAK!!!
        _oCamTarget.OnStart();

        Debug.Log("8. Body Assembly.");  //###???  new WaitForSeconds(nDelayForGuiCatchup);		//###WEAK!!!

        //_oFluid.OnStart();								//###CHECK: Keep interleave

        SetGameModeBasicInteractions(true);

        //=== Find the static scene colliders in 'SceneColliders' node and initialize them ===
        //Debug.Log("CGame.StartGame() Registering Static Colliders: " + s_aColliders_Scene.Length);
          //  if (s_aColliders_Scene != null)
            //foreach (CCollider_OBS oColStatic in s_aColliders_Scene)		// Colliders that are marked as static registered themselves to us in their Awake() so we can start and destroy them
               // oColStatic.OnStart();

        //StartCoroutine(Coroutine_Update100ms());
        StartCoroutine(Coroutine_Update500ms());

        _GameIsRunning = true;
        enabled = true;
        Debug.Log("+++ GameIsRunning ++");

        Debug.Log("7. Scene settling time.");  //###???  new WaitForSeconds(2.0f);		//###DESIGN??  ###TUNE??
        ///_oGui.ShowSceneBlanker(false);
        ///_oGui.ShowPanelGameLoad(false);

        //=== Check result of user authentication ===
        /*
        if (oWWW != null) {
            yield return oWWW;
            string sResultAuth = oWWW.text;
            _DemoVersion = sResultAuth.Contains("Result=OK") == false;		//###IMPROVE: Create parse routine and return server errors
            Debug.Log("Auth Results = " + sResultAuth);
            if (_DemoVersion == false)
                Debug.Log("Starting game in non-demo mode.");
        }*/
        //_DemoVersion = false;
        //if (_DemoVersion)
        //	Debug.Log("Starting game in demo mode.");		//###TODO: Temp caption!

        ///		if (_bRunningInEditor == false)
        ///			CUtility.WndPopup_Create(EWndPopupType.LearnToPlay, null, "Online Help", 50, 50);	// Show the help dialog at start... ###BUG: Does not change the combo box at top!

        SetForegroundWindow(_hWnd_Unity);           //###WEAK: Can get rid of??

        //if (CGame.INSTANCE._GameMode == EGameModes.None)        //####TEMP
        //    return;

        //=== Create the body publicly-editable body definitions that can construct and reconstruct CBody instances ===
        //CGame.INSTANCE._nNumPenisInScene_BROKEN = 0;

        //###NOTE: For simplification in pose files we always have two bodies in the scene with man/shemale being body 0 and woman body 1
        //CreateBody(0);
        //      //CreateBody(1);
        _aBodyBases[0] = new CBodyBase(0, EBodySex.Woman);
        //###BROKEN _aBodyBases[0].SelectBody();

        TemporarilyDisablePhysicsCollision();

        ///SetPenisInVagina(false);		// We initialize the penis in v****a state to false so v****a track colliders don't kick in at scene init

        if (CGame.INSTANCE._GameMode == EGameModes.Play)
            ScenePose_Load("Standing", false);          // Load the default scene pose

        //###TODO ##NOW: Init GUI first!!
        //iGUISmartPrefab_WndPopup.WndPopup_Create(new CObject[] { oObj }, "Game Play", 0, 0);		//###TEMP

        //Time.timeScale = 0.05f;		//###REVA ###TEMP   Gives more time for cloth to settle... but fix it some other way (with far stronger params??)

        ChangeGameMode(_GameModeAtStartup);             // Set the initial game mode as statically requested

        Debug.LogFormat("Time at startup end: {0}", Time.time - _nTimeAtStart);
        //ScenePose_Load("Standing", false);          // Load the default scene pose
    }