Topic: Collection of UFE Mods and Improvements
1.5 Engine Modifications:
This post will attempt to provide some improvements to the engine. I have only been using Unity for about 6 months, so I apologize if some of the code is not the most optimized.
Mobile Improvements:
Keep mobile devices awake while the game is running
First off, Open up UFE.cs and find Awake() on line 725 and insert
Screen.sleepTimeout = SleepTimeout.NeverSleep; after
Prevent the popup menus from being tiny when viewed on tablets
- Instead of altering resolution, you can add a scalable matrix that will stretch the entire view as a whole.
Open IntroScript.cs and add the following variables
private float originalWidth = 1280.0f;
private float originalHeight = 720.0f;
private Vector3 scale;
Scroll down and find if (hostGameIsOpen) in the OnGUI and above it insert
scale.x = Screen.width / originalWidth;
scale.y = Screen.height / originalHeight;
scale.z = 1f;
Matrix4x4 svMat = GUI.matrix;
GUI.matrix = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, scale);
For every instance of Screen.width and Screen.height below this, replace them with originalWidth and originalHeight respectively
At the end of the conditionals (if, else if, else, etc) add
GUI.matrix = svMat;
just above the last two }'s
Open GUIScript.cs and add the same variables at the top
private float originalWidth = 1280.0f;
private float originalHeight = 720.0f;
private Vector3 scale;
Scroll down the OnGUI function and below GUI.skin = customSkin add
scale.x = Screen.width / originalWidth;
scale.y = Screen.height / originalHeight;
scale.z = 1f;
Matrix4x4 svMat = GUI.matrix;
GUI.matrix = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, scale);
For every instance of Screen.width and Screen.height below this, replace them with originalWidth and originalHeight respectively until you reach if (!isRunning || UFE.config.player1Character == null) return; and above it insert
GUI.matrix = svMat;
Standard Improvements:
Adding a background for 3D character selection
Create a plane in Unity (under Gameobject, 3D Object)
Set the position as 0, 4, 1 and rotation as 90, 180, 0 with a scale of 2.5, 0.01, 1.3
Next, you will need a material (Assets, Create, Material) and attach this material to the plane
Add the wallpaper you would like to this material (Do not include the text or icons)
Open UFE.cs and below the variable private static GameObject currentScreen; add
private static GameObject supportScreen;
After every instance of Destroy(currentScreen); add
if (supportScreen != null) {
Destroy (supportScreen);
}
In private static void _StartCharacterSelect(float fadeTime) and private static void _StartStageSelect(float fadeTime), find the currentScreen = (GameObject) Instantiate... and below it add
if (config.persistentScreen != null) {
supportScreen = (GameObject) Instantiate(config.persistentScreen);
}
Now you will want to set the background image for both the character select and stage select screen to an image with no background, just the text and icons.
An example of the Character Selection Screen background would be
Follow the tutorial at http://www.ufe3d.com/forum/viewtopic.php?id=289 but add the p1/p2SelectInstance variables to UFE.cs as public static
Now open up the GlobalInfo.cs and find public GameObject characterSelectionScreen and below it add
public bool modelSelection;
public GameObject persistentScreen;
Open GlobalEditorWindow.cs (in the UFE/Editor folder) and find globalInfo.inroMusic = ... and below it add
globalInfo.persistentScreen = (GameObject) EditorGUILayout.ObjectField("Persistent Menu Background:", globalInfo.persistentScreen, typeof(UnityEngine.GameObject), true);
globalInfo.modelSelection = EditorGUILayout.Toggle("3D Character Selection:", globalInfo.modelSelection);
Open CharacterSelectionScript and scroll down to the Start() function and find where you added the OnCharacterHighlighted call and wrap it with
if (UFE.config.modelSelection) {
}
Scroll down to the DoFixedUpdate() section and for all of the if's that OnCharacterHighlighted was added to, add
UFE.config.modelSelection &&
at the beginning of the conditions in the if
Scroll down to the OnGUI section and uncomment the p1/p2SelectBig code and instead wrap both with
if (!UFE.config.modelSelection) {
}
Open StageSelectionScript.cs and find if (GUI.Button(returnButtonRect, "", returnButtonStyle)) UFE.StartCharacterSelect(2); in the OnGUI() section. Below this, wrap the two profilePictureBig if's with
if (!UFE.config.modelSelection) {
}
Find the void StartGame() function and above the UFE.StartGame(3); add
if (UFE.config.modelSelection) {
if (UFE.p1SelectInstance != null) {
Destroy(UFE.p1SelectInstance);
}
if (UFE.p2SelectInstance != null) {
Destroy(UFE.p2SelectInstance);
}
}
Finally, open the UFE.cs and after the public static void StartCharacterSelect(float fadeTime){ add
if (UFE.config.modelSelection && Camera.main.transform.rotation != Quaternion.identity) {
Camera.main.transform.localPosition = new Vector3 (-0.2f, 4.0f, -42.0f);
Camera.main.transform.localRotation = Quaternion.identity;
}
Note: You should set the MainCamera default position to 0, 4, -10 as the UFE tutorial suggested for this to work
You now have the option to click 3D Character Selection in the UFE Global Config under Screen Options
You will want to drag the Plane prefab you made above to the newly added "Persistent Menu Background" UFE Global Config option under Screen Options if you enable the 3D Character Selection. This will give you 3D selection with a background.
Arcade Mode with GUI option and random character selection:
* NEW / UPDATED
Open up the IntroScript.cs and add the following variables
public GUIStyle arcadeButtonStyle;
private Rect arcadeButtonRect;
In the Start() function, add
arcadeButtonRect = new Rect(0, 0, arcadeButtonStyle.normal.background.width, arcadeButtonStyle.normal.background.height);
In the same function, find if (UFE.isNetworkAddonInstalled){ and add
arcadeButtonRect = SetResolution(arcadeButtonRect, 380);
then in the else from the same conditional add
arcadeButtonRect = SetResolution(arcadeButtonRect, 340);
Scroll down to the OnGUI function and find the first if (startingCharacterSelect... and above it add
if (startingCharacterSelect && UFE.config.arcadeMode) GUI.color = new Color(1,1,1,(Mathf.PingPong(Time.time * 15, 1))/ 2);
if (GUI.Button(arcadeButtonRect, "", arcadeButtonStyle) && !startingCharacterSelect) {
UFE.PlaySound(selectSound);
UFE.config.arcadeMode = true;
UFE.DelayAction(this.StartCharacterSelect, 0.5f);
startingCharacterSelect = true;
}
GUI.color = Color.white;
then inside the original if (startingCharacterSelect) statement add
&& UFE.config.arcadeMode
and below UFE.PlaySound(selectSound); add
UFE.config.arcadeMode = false;
Now open the GlobaInfo.cs, find public class GlobalInfo: ScriptableObject and at the bottom of that list add
public bool arcadeMode;
This sets up the GUI for arcade mode and now you can go to the IntroScreen.prefab and in the Editor set the off image for the Normal background of Arcade Button Style and the on image for the Hover and Active.
Open the CharacterSelectionScript. Find the Start() function and at the bottom of it add
if (UFE.config.arcadeMode) {
UFE.SetCPU (1, false);
p1PlayerSelected = true;
p1AISelected = false;
UFE.SetCPU (2, true);
p2PlayerSelected = false;
p2AISelected = true;
int aIndex = UnityEngine.Random.Range(0, UFE.config.characters.Length);
this.SelectCharacter(2, aIndex);
OnCharacterHighlighted(2, aIndex);
}
Now scroll down to the OnGUI() and replace that entire function with
void OnGUI(){
GUI.skin = customSkin;
/*p1JoystickName = "";
p2JoystickName = "";
string[] joysticks = Input.GetJoystickNames();
foreach(string joystickName in joysticks){
if (joystickName != p2JoystickName) p1JoystickName = joystickName;
if (joystickName != p1JoystickName) p2JoystickName = joystickName;
}*/
Texture2D p1SelectedBig = null;
Texture2D p2SelectedBig = null;
//GUI.BeginGroup(SetResolution(new Rect(457, 465, 378, 220)));{
GUI.BeginGroup(SetResolution(charactersGrid));{
int xCount = 0;
int yCount = 0;
int currentIndex = 0;
foreach(CharacterInfo character in UFE.config.characters){
float xPos = 112 * xCount;
float yPos = 68 * yCount;
xCount ++;
if (xCount == gridColumns){
yCount ++;
xCount = 0;
}
GUI.DrawTexture(SetResolution(new Rect(xPos, yPos, 102, 58)), character.profilePictureSmall);
// If the player clicked over a character portrait...
if (GUI.Button(SetResolution(new Rect(xPos, yPos, 102, 58)), "")){
// Check if he was playing online or not...
if (Network.peerType == NetworkPeerType.Disconnected){
// If it's a local game, update the corresponding character immediately...
if (UFE.config.player1Character == null) {
this.SelectCharacter(1, currentIndex);
OnCharacterHighlighted(1, currentIndex);
} else if (!UFE.config.arcadeMode) {
if (UFE.config.player2Character == null) {
this.SelectCharacter(2, currentIndex);
OnCharacterHighlighted(2, currentIndex);
}
}
}else{
// If it's an online game, find out if the local player is Player1 or Player2...
// And only update the selection for the local player...
int localPlayer = UFE.GetLocalPlayer();
if (localPlayer == 1 && UFE.config.player1Character == null){
this.SelectCharacter(1, currentIndex);
}else if (localPlayer == 2 && UFE.config.player2Character == null){
this.SelectCharacter(2, currentIndex);
}
}
}
//GUI.DrawTextureWithTexCoords(SetResolution(new Rect(xPos, yPos, 86, 105)), character.profilePictureSmall, new Rect(0, 0, 1, 1));
//if (GUI.Button(SetResolution(new Rect(xPos, yPos, 86, 105)), character.profilePictureSmall)) {
// .
//}
//if (UFE.config.player1Character != null)
//GUI.color = new Color(1,1,1,(Mathf.Sin(Time.time * 20) + 1)/ 2);
if (p1HoverIndex == currentIndex && p1HoverIndex == p2HoverIndex){
bool selTemp = (UFE.config.player1Character != null && UFE.config.player1Character != null)? true : false;
DrawHud(new Rect(xPos, yPos, 102, 58), p1P2Hud, selTemp);
//GUI.DrawTexture(SetResolution(new Rect(xPos, yPos, 86, 105)), p1P2Hud);
p1SelectedBig = character.profilePictureBig;
p2SelectedBig = character.profilePictureBig;
}else{
if (p1HoverIndex == currentIndex){
DrawHud(new Rect(xPos, yPos, 102, 58), p1Hud, (UFE.config.player1Character != null));
//GUI.DrawTexture(SetResolution(new Rect(xPos, yPos, 86, 105)), p1Hud);
p1SelectedBig = character.profilePictureBig;
}
if (p2HoverIndex == currentIndex){
DrawHud(new Rect(xPos, yPos, 102, 58), p2Hud, (UFE.config.player2Character != null));
//GUI.DrawTexture(SetResolution(new Rect(xPos, yPos, 86, 105)), p2Hud);
p2SelectedBig = character.profilePictureBig;
}
}
//GUI.color = Color.white;
currentIndex ++;
}
}
}GUI.EndGroup();
if (UFE.config.modelSelection) {
scale.x = Screen.width / originalWidth;
scale.y = Screen.height / originalHeight;
scale.z = 1f;
Matrix4x4 svMat = GUI.matrix;
GUI.matrix = Matrix4x4.TRS (Vector3.zero, Quaternion.identity, scale);
int fontSize = GUI.skin.label.fontSize;
GUI.skin.label.fontSize = 40;
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUI.Label (new Rect (61, 554, 200, 80), UFE.config.characters [p1HoverIndex].characterName);
GUI.skin.label.alignment = TextAnchor.UpperRight;
GUI.Label (new Rect (1019, 554, 200, 80), UFE.config.characters [p2HoverIndex].characterName);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUI.skin.label.fontSize = fontSize;
GUI.matrix = svMat;
} else {
if (p1SelectedBig != null) {
GUI.DrawTexture (SetResolution (new Rect (79, 112, 311, 496)), p1SelectedBig);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUI.skin.label.fontSize = 30 * (Screen.height / 720);
GUI.Label (SetResolution (new Rect (178, 597, 250, 50)), UFE.config.characters [p1HoverIndex].characterName);
if (p2SelectedBig != null) {
GUI.DrawTextureWithTexCoords (SetResolution (new Rect (902, 113, 311, 496)), p2SelectedBig, new Rect (0, 0, -1, 1));
GUI.skin.label.alignment = TextAnchor.UpperRight;
GUI.skin.label.fontSize = 30 * (Screen.height / 720);
GUI.Label (SetResolution (new Rect (860, 597, 250, 50)), UFE.config.characters [p2HoverIndex].characterName);
}
}
GUI.skin.label.alignment = TextAnchor.UpperLeft;
// GUI.DrawTexture(SetResolution(new Rect(61, 554, p1Overlay.width, p1Overlay.height)), p1Overlay);
// GUI.DrawTexture(SetResolution(new Rect(1130, 554, p2Overlay.width, p2Overlay.height)), p2Overlay);
if (GUI.Button(returnButtonRect, "", returnButtonStyle)) UFE.StartIntro(2);
if (UFE.config.arcadeMode) {
return;
}
p1PlayerSelected = GUI.Toggle (SetResolution (new Rect (420, 170, 177, 116)), p1PlayerSelected, "", p1PlayerStyle);
if (p1PlayerSelected) {
p1AISelected = false;
UFE.SetCPU (1, false);
}
if (!p1PlayerSelected && !p1AISelected)
p1PlayerSelected = true;
p1AISelected = GUI.Toggle (SetResolution (new Rect (420, 310, 177, 116)), p1AISelected, "", p1AIStyle);
if (p1AISelected && p1PlayerSelected) {
p1PlayerSelected = false;
UFE.SetCPU (1, true);
}
p2PlayerSelected = GUI.Toggle (SetResolution (new Rect (691, 170, 177, 116)), p2PlayerSelected, "", p2PlayerStyle);
if (p2PlayerSelected && p2AISelected) {
p2AISelected = false;
UFE.SetCPU (2, false);
}
if (!p2PlayerSelected && !p2AISelected)
p2PlayerSelected = true;
p2AISelected = GUI.Toggle(SetResolution(new Rect(691, 310, 177, 116)), p2AISelected, "", p2AIStyle);
if (p2AISelected && p2PlayerSelected) {
p2PlayerSelected = false;
UFE.SetCPU (2, true);
}
}
If you did not add the 3D character selection, make sure to remove any of the lines with OnCharacterHighlighted
You now have player 2 automatically selected at random and set to CPU when choosing player 1.
Optional if you want to have ongoing rounds:
In the GUIScript.cs, you will want to find the OnGameEnds function and edit it to be
if (UFE.config.arcadeMode && winner == UFE.GetPlayer1 ()) {
isRunning = false;
Destroy (player1NameGO);
Destroy (player2NameGO);
Destroy(infoGO);
Destroy (timerGO);
UFE.SetPlayer2 (UFE.config.characters [UnityEngine.Random.Range (0, UFE.config.characters.Length)]);
UFE.StartStageSelect(2);
Destroy(mainAlertGO);
} else {
// Fires when game ends
showEndMenu = true;
isRunning = false;
Destroy (player1NameGO);
Destroy (player2NameGO);
Destroy(infoGO);
Destroy (timerGO);
}
You may also want to set a variable for the number of rounds played for a limit and possibly an intermediate screen or alert providing progress.