public string _sNameCBodyInstanceMember; // The base part of the name (without suffix) #endregion Fields #region Methods //--------------------------------------------------------------------------- INIT //###SOON: Redo the crappy static create to just create component with a separate Initialize() with the proper arguments public static CBMesh Create(GameObject oBMeshGO, CBodyBase oBodyBase, string sNameCBodyInstanceMember, Type oTypeBMesh, Boolean bKeepBlenderShare = false) { //===== Important static function that reads a Blender mesh definition stream and create the requested CBMesh-derived entity on the provided gameObject node ===== //=== Create the game object that will host our component === if (oBMeshGO == null) { // When CBody or test meshes are creating itself this will be set, null for rim and softbody parts. ###WEAK!!! oBMeshGO = new GameObject(sNameCBodyInstanceMember, oTypeBMesh); // If we're here it means we're rim or a body part. Create a new game object... ####DEV ####NOW: Name problem here! oBMeshGO.transform.parent = oBodyBase._oMeshMorphResult.transform; //... Parent it to the body if specified (body is always specified for rim or body parts) } //=== Create our component (of the requested type) from the above-created game object === CBMesh oBMesh = (CBMesh)CUtility.FindOrCreateComponent(oBMeshGO.transform, oTypeBMesh); oBMesh._oBodyBase = oBodyBase; // Push-in some important args manually (so we don't have to push them in OnDeserializeFromBlender() oBMesh._sNameCBodyInstanceMember = sNameCBodyInstanceMember; oBMesh.gameObject.name = oBMesh._sNameCBodyInstanceMember; //###DESIGN#11!!! IMPROVE THIS CRAPPY Node name!! Give Unity node the 'Blender node name (i.e. not path to instance variable string!) oBMesh._bKeepBlenderShare = bKeepBlenderShare; //=== Obtain the name of the Blender mesh object from the data-member of Blender's CBody class we're paired to === string sCBodyDataMember = oBodyBase._sBlenderInstancePath_CBodyBase + sNameCBodyInstanceMember; // Fully-qualified path to the CBody data member currently pointing to the mesh we need. oBMesh._sNameBlenderMesh = CGame.gBL_SendCmd("CBody", sCBodyDataMember + ".GetName()"); // Store the name of the Blender object holding the mesh so we can directly access. oBMesh.OnDeserializeFromBlender(); // Fully deserialize the mesh from Blender. (Virtual call that cascades accross several classes in order) oBMesh.FinishIntialization(); //###DESIGN ###CHECK? return oBMesh; }
Transform _oWatchBone; // Bone position we watch from our owning body to 'autotune' cloth simulation parameters so cloth stays on body during rapid movement (e.g. pose changing) #endregion Fields #region Methods public static CBCloth Create(CBodyBase oBodyBase, string sNameCloth, string sClothType, string sNameClothSrc, string sVertGrp_ClothSkinArea) { // Static function override from CBMesh::Create() to route Blender request to Body Col module and deserialize its additional information for the local creation of a CBBodyColCloth string sBodyID = "CBodyBase_GetBodyBase(" + oBodyBase._nBodyID.ToString() + ")."; CBCloth.s_sNameClothSrc_HACK = "aCloths['" + sNameCloth + "']"; CGame.gBL_SendCmd("CBody", sBodyID + "CreateCloth('" + sNameCloth + "', '" + sClothType + "', '" + sNameClothSrc + "', '" + sVertGrp_ClothSkinArea + "')"); // Create the Blender-side CCloth entity to service our requests //CGame.gBL_SendCmd("CBody", sBodyID + CBCloth.s_sNameClothSrc_HACK + ".UpdateCutterCurves()"); //CGame.gBL_SendCmd("CBody", sBodyID + CBCloth.s_sNameClothSrc_HACK + ".CutClothWithCutterCurves()"); CGame.gBL_SendCmd("CBody", sBodyID + CBCloth.s_sNameClothSrc_HACK + ".PrepareClothForGame()"); //###IMPROVE#13!! Damn period before... make consistent!! CBCloth oBCloth = (CBCloth)CBMesh.Create(null, oBodyBase, "." + CBCloth.s_sNameClothSrc_HACK + ".oMeshClothSimulated", typeof(CBCloth)); // Obtain the simulated-part of the cloth that was created in call above //####IDEA: Modify static creation by first creating instance, stuffing it with custom data and feeding instance in Create to be filled in! return oBCloth; }
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 }
public CMorphChannel(CBodyBase oBodyBase, string sNameMorphChannel) { _oBodyBase = oBodyBase; //=== Get the morphing records from Blender. Code finds the proper shape key, calculates delta and sends us records that our C++ code processes containing vert and delta vector === _aMorphDataRecords = CByteArray.GetArray_FLOAT("'CBody'", _oBodyBase._sBlenderInstancePath_CBodyBase + ".CMorphChannel_GetMorphVerts('" + sNameMorphChannel + "')"); }
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 }